In the context of my Classification of HTTP-based APIs @hanonymity today asked me, how I would classify the CouchDB API.
Ok, let’s see. Going to the HTTP Document API immediately reveals that the API definitely violates the hypermedia constraint (see last paragraph) because there is an API documentation in the first place. The only thing one would expect to see for a RESTful API is a set of media type specifications along the lines “The CouchDB API uses the following media types and link relations….which are specified here…”.
Next, let’s check if the API can be classified as HTTP-based Type II. The fastest way to verify this is usually to look for the use of only specified media types and it is immediately obvious that the CouchDB uses the generic media type application/json and not a specific one that would make the messages self-descriptive. CouchDB API fails the test for HTTP-based Type II, too.
This leaves us with the question whether the API is HTTP-based Type I or if we have to let go all hope because it must be classified as RPC URI-Tunneling. The thing to look out for is of course the use of action names in URIs. It does not take a lot of browsing through the API documentation to reveal that the CouchDB API designers knew what they were doing. The API very thoroughly leverages HTTP mechanics and we can happily conclude that the API is an HTTP-based Type I API.
Is it a problem that the CouchDB API violates two out of four of REST’s interface constraints and is therefore not REST at all? I do not think so, because I would not consider achieving loose coupling between a database (backend) and the component that uses the database to be a very useful goal. At least not at the cost that you have to pay on the client side and also because there is strong coupling around the schema anyway between a database and the code that is using it.
However, I think CouchDB API shows quite nicely how an API can still benefit from the simplicity induced by HTTP-based Type I even if we cannot label the API as REST.
A note on the COPY method: It would be helpful to say in the API documentation that the COPY extension method is actually WebDAV’s COPY method. And while we are at it, it makes also sense to note that COPY does not really fit HTTP because COPY is a method that works on two resources (Source and Destination) while HTTP does not support such method semantics. For example, caches would not understand that they need to flush the representations of the (now overwritten) destination resource.
This is not a question of RESTfulness though. It would be entirely possible to design an architecture that adheres to the REST style and provides methods that work on two resources.
Hey,
thanks for the great writeup. We’ve had this discussion quite a few times. While out of the box the hypermedia constraint is not adhered, you can make CouchDB a fully self-descriptive hypermedia source using a combination of show and list functions, the rewriter and vhosts.
I don’t really follow the HTTP type II exclusion thing. Would we have to use application/json+couchdbdocument or somesuch?
Either way, both “relaxations” from pure REST evolved out of practical experience.; )
Thanks again!
Cheers
Jan
–
Hi Jan,
can you provide a documentation pointer to “using a combination of show and list functions, the rewriter and vhosts”? Sounds interesting.
Regarding the message self-descriptiveness: When you use a generic format, understanding the processing intent requires out of band knowledge (unless the intent really only is: “parse this as JSON”. IOW, the real meaning of the message can not be inferred from the message itself.
However, the question is whether that is a useful requirement for database interactions because the database is not a service with specific application semantics.
It is an interesting point because you could place all the necessary processing semantics into headers and just treat the body as somewhat opaque payload (like a PDF is for example). Let me look at the hypermedia support you mentioned, that seems related.
Thanks,
Jan
Hi Jan,
Show and List functions let you transform documents and view results into whatever you want it to be. You could add hyperlinks for resource discovery.
http://wiki.apache.org/couchdb/Formatting_with_Show_and_List
The rewriter and vhosts don’t have documentation yet (they were added in the last weeks). In short, the rewriter lets you map any url /db/_design/doc/_rewrite/* to whatever else. This alone doesn’t help much, but in combination with vhosts, you gain full control over the CouchDB URL space. It simply maps http://example.com/ to /db/_design/doc/_rewrite based on the request Host header.
Together with shows and lists you can make fully-hypertexty CouchDB.
For the content-type, both is correct :) CouchDB assumes a “parse this as JSON” on the client and then the client can do whatever; there is no implied semantics. It does though reserve the _* namespace for properties (_id, _rev. etc). So application/json+couchdb would be more appropriate, but that wouldn’t fly with any clients in the wild.
(even worse theoretically, by default CouchDB sends text/plain with the JSON so browsers render the JSON instead of offering a download. Only if you request with application/json, you get that content type. But this is a major practicality win over the “pure” solution)
Cheers
Jan
–
[...] by Grig Gheorghiu. Half overview of HTTP and rest, half overview of Restish framework. Classifying the CouchDB API – An evaluation of the RESTfulness of the CouchDB API. (by Jan [...]
[...] Classifying the CouchDB API [...]