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

3

36

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&maxResults=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!

Selfexpression answered 16/5, 2011 at 19:17 Comment(1)
I wish I could +10 this question.Vltava
C
22

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

/users{?surname,maxresults}
Chari answered 16/5, 2011 at 19:26 Comment(2)
The URI Template spec looks very useful.Marietta
The above link does not work anymore, use https intead, tools.ietf.org/html/rfc6570Numb
A
6

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.

Alienee answered 17/5, 2011 at 0:12 Comment(2)
Maybe I'm missing the point, but this won't work if your resource isn't HTML.Vltava
This html form is a way to formulate the GET request, what you get back is in whatever media type format you asked for in...could be (and probably would be) something completely different.Parra
H
1

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.

Helaina answered 21/6, 2015 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.