The most interesting problem came in designing the query scheme for the REST interface. There seems to be a couple different ways to implement it with no real consensus as to which is the "right" way. As with most things, I suspect it depends on how you've implemented other pieces of the architecture and even personal preference. Below I describe three approaches I considered. The nice thing with REST is there's nothing stopping you from implementing all of these approaches in your interface.
NB: I'm no REST expert so the information below is my observations rather than any best practices. I'd love for anyone who knows better to chime into the discussion.
POST query parameters/document
In this approach, you provide a search endpoint, say something unoriginal like '
/search
', and queries are POSTed to that URI. The query is either a set of form encoded key-value pairs or a search document using a schema shared between the client and server.This approach seems closer to RPC than REST to me, but may be the best approach if your search functionality requires a more complex exchange of information than simple key-value pairs allow. The obvious downside to this approach is that there is no way to bookmark a query or email/IM a query to someone else. This approach also can't take advantage of the caching built into the HTTP spec.
GET query string
Similar to above, you expose a URI endpoint, possibly something like
/search
, and queries are sent to that endpoint with the parameters encoded in the query string of the URL, e.g. http://www.google.com/search?q=REST+query+stringThis approach improves on the bookmarkability of searches, since all of the parameters are in the URL. However, the use of the query string may interfere with caching as described in Section 13.9 of the HTTP spec. Overall, I think there is nothing inherently un-RESTful about this approach, especially if you provide more resource-oriented URIs than
/search
, e.g. /documents?author=Reed
. In my head, I interpret the latter as "give me all of the document resources but filter on the author Reed. Removing the query string will still give you a resource (or collection of resources in this case).Where this approach falls down is when you start trying to represent hierarchical or taxonomic queries with the query string, e.g.
http://lifeforms.org?k=kingdom&p=phylum&c=class&o=order&f=family&g=genus&s=species
as described on the RestWiki.Encoding query parameters into the URI structure
In this approach the query parameters are encoded directly into the URI structure, e.g.
/documents/authors/Reed
, rather than using the query string. Another example of is described at Stack Overflow.This approach solves both the bookmarkability and the caching issues of the previous approaches, but can introduce some ambiguity, especially if your resources aren't strictly hierarchical in nature. The biggest stumbling block for me was this: looking at the URI
/documents/authors/Reed
, it's not immediately clear what will be returned. For example, if I sent you the URI /documents
you might infer that you would get a list or the contents of some documents. From the URI /documents?author=Reed
, you might infer that the resource(s) returned would be documents authored by Reed. So what might you expect to get from the URI /documents/authors/Reed
? Information about the author Reed or all documents authored by Reed?How important is this? I guess it's really up to you. A machine likely infers about as much from
/documents/authors/Reed
as it does from /documents?author=Reed
.