开发者

How can I use HATEOAS and Query Parameters for RESTful search?

I would like to design a RESTful search URI using query parameters. For example, this URI returns a list of all users:

GET /users

And the first 25 users with the last name "Harvey":

GET /users?surname=Harvey&maxRe开发者_如何学Pythonsults=25

How can I use hypermedia to describe what query parameters are allowed by the "/users" resource? I noticed that the new Google Tasks API just documents all the query parameters in the reference guide. I will document the list, but I would like to do it with HATEOAS too.

Thank you in advance!


Using the syntax described in the current draft of the URI template spec you would do:

/users{?surname,maxresults}


The other option is to use an html form:

<form method="get" action="/users">
   <label for="surname">Surname: </label>
     <input type="text" name="surname"/>
   <label for="maxresults">Max Results: </label>
     <input type="text" name="maxresults" value="25"/> <!-- default is 25 -->
   <input type="submit" name="submitbutton" value="submit"/>
</form>

A form like this fully documents the available options and any defaults, it creates the specified URL and can be annotated with any further documentation that you care to put there.


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:

  1. 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);

  2. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜