I am no REST expert, but let me throw in my 2¢:
On the human Web, HTML forms are often used to build a URI to a representation of the search results. Problem is, the programmable Web does not have forms. But you could easily define something something analogous yourself, that is:
Define a media type for search descriptions, let's say application/prs.example.searchdescription+json
(but take note of the P.S. at the end of this answer);
Expose a sub-resource that represents a search for users, /users/search
.
The second step would be achieved by linking to that sub-resource from somewhere else. For instance, let's say the client has requested GET /users
. It might receive something like this:
{ _links: [ …, { rel: "search", href: "/users/search" }, …] }
The client could follow that link and POST
a search specification to that resource URI, for example:
POST /users/search
…
Content-Type: application/prs.example.search-definition+json
…
{ criteria: { surname: "Harvey" }, maxResults: 25 }
Here, criteria
contains a (partial) representation of the objects to be found. This could be made into an arbitrarily complex description.
To a request as described above, the server might then reply with status code 200 OK
and, in the entity body, a link to a resource representing the results for the posted search:
{ _links: [ { rel: "results", href: "/users?surname=Harvey&maxResults=25" } ] }
The client can then navigate to the URI with the results
relation to get the search results, without ever having had to assemble an URI itself.
P.S.: When I originally wrote this, I had not yet realized that defining new media types all the time can become problematic. Mark Nottingham blogged about "media type proliferation" and how to combat it by making use of the profile
link relation.