tags:

views:

242

answers:

3

I read the article at http://stackoverflow.com/questions/1296421/rest-complex-applications and it answers some of my questions, but not all.

I am designing my first REST application and need to return "subset" lists to GET requests. Which of the following is more "RESTful"?

/patients;listType=appointments;date=2010-02-22;user_id=1234

or

/patients/appointments-list;date=2010-02-22;user_id=1234

or even

/appointments/2010-02-22/patients;user_id=1234

There will be about a dozen different lists that I need to return. In some of these, there will be several filtering parameters and I don't want to have big 'if' statements in my server code to select the subsets based on which parameters are present. For example, I might need all patients for a specific doctor where the covering doctor is another and the primary doctor is yet another. I could select with

/patients;rounds=true;specific_id=xxxx;covering_id=yyyy;primary_id=zzzz

but that would require complicated branching logic to get the right list, where asking for a specific subset (rounds-list) will achieve that same thing.

Note that I need to use matrix parameters instead of query parameters because I need to do filtering at several levels of the URL. The framework I am using (RestEasy), fully supports matrix parameters.

A: 

Ralph,

the particular URI patterns are orthogonal to the question how RESTful your application will be.

What matters with regard to RESTfulness is that the client discovers how to construct the URIs at runtime. This can be achieved either with forms or URI templates. Both hypermedia controls tell the client what parameters can be used and where to put them in the URI.

For this to work RESTfully, client and server must know the possible parameters at design time. This is usually achieved by making them part of the specification of the link relationship.

You might for example define a 'my-subset' link relation to have the meaning of linking to subsets of collections and with it you would define the following parameters:

listType, date, userID.

In a link template that spec could be used as

<link rel="my-subset' template="/{listType}/{date}/patients;user_id={userID}"/>

Note how the actual parameter name in the URI is decoupled from the specified parameter name. The value for userID is late-bound to the URI parameter user_id.

This makes it possible for the URI parameter name to change without affecting the client.

You can look at OpenSearch description documents (http://www.opensearch.org) to see how this is done in practice.

Actually, you should be able to leverage OpenSearch quite a bit for your use case. Especially the ability to predefine queries would allow you to describe particular subsets in your 'forms'.

But see for yourself and then ask back again :-)

Jan

Jan Algermissen
I making my way through the opensearch documents.Are you suggesting that every resource on a REST server must be "discoverable" by calling some other URL on the server? I can't just publish a document that says something like "If you need to get all blue widgets, use the URL '/widgets;color=blue'?
Ralph
That's correct.
Darrel Miller
Yes, as Darrel said.In a sense you can roughly think of it this way: provide the document you have in mind in machine readable form (media type) at runtime and let the client react on it.Jan
Jan Algermissen
Can you provide a citation or defense for this claim: "the particular URI patterns are orthogonal to the question how RESTful your application will be"?
David James
I want to push back against this statement: "the particular URI patterns are orthogonal to the question how RESTful your application will be." According to p. 233 of RESTful Web Services by Richardson and Ruby, there are better and worse ways to construct URI patterns to match up with their "Resource-Oriented Architecture" (ROA). In summary: (1) make URIs stand for resources (e.g. nouns), (2) make URIs constructible by clients, (3) use slashes to go from general to specific, (4) use commas when order matters, (5) use semicolons when it does not, and (6) use query variables for algorithms.
David James
FWIW, I agree that resource discoverability does matter. I'm glad Jay brought it up because it does sometimes get overlooked. However, it is only part of building a good RESTful API -- building good URIs is also essential.
David James
URI design influences the ease of implementation but they do not influence whether an application is RESTful or not. There is no constraint in REST that applies to how you structure your URIs.
Jan Algermissen
+2  A: 

I would recommend that you use this URL structure:

/appointments;user_id=1234;date=2010-02-22

Why? I chose /appointments because it is simple and clear. (If you have more than one kind of appointment, let me know in the comments and I can adjust my answer.) I chose the semicolons because they don't imply hierarchy between user_id and date.

One more thing, there is no reason why you should limit yourself to just one URL. It is just fine to have multiple URL structures that refer to the same resource. So you might also use:

/users/1234/appointments;date=2010-02-22

To return a similar result.

That said, I would not recommend using /dates/2010-02-22/appointments;user_id=1234. Why? I don't think, in practice, that /dates refers to a resource. Date is an attribute of an appointment but is not a noun on its own (i.e. it is not a first-class kind of thing).

David James
A: 

I can relate to what David James answered.
The format of your URIs can be like he suggested:

/appointments;user_id=1234;date=2010-02-22

and / or

/users/1234/appointments;date=2010-02-22

while still maintaining the discoverability (at runtime) of your resource's URIs (like Jan Algermissen suggested).

Falx