Monday 6 January 2014

RESTful design notes

Object Graphs, Sub Resources

For deep collections or deep object graphs should you return a fully hydrated object graph?
Or do you return a link to a child resource? This is debated here.

A discussion about POSTing object graphs is here. The answer may depend upon your processing logic. If you expect to be able to update the whole object graph in one atomic operation then post the whole object graph. If child resources can be added separately, independently, and may fail for different reasons individually then POST the aggregate root and then POST the sub resources separately.

For GETs:
Consider composition versus aggregation. Is the child's lifetime dependant upon the parent? When the parent is destroyed is the child always destroyed (e.g. composition)? In this scenario a subresource may be more appropriate:

GET /countries
GET /countries/US/States

The Netflix API demonstrates links to child resources. Performing a search on titles, returns a title (e.g.)
http://api-public.netflix.com/catalog/titles/movies/60021896 but also links to children within the title (such as the directors, the cast, the awards.

If it's not a composition relationship, and the resource indicates an aggregation or association relationship then you may consider the following pattern:
/person/123/dogs returns a 307 redirect to /dogs?person=123

Empty Collections

If you do a get on /addresses?postcode=RG17XX and there are no matching addresses you should return 200 with an empty collection, not a 404. Remember 404 is an ERROR condition. Not finding a match is not an error.

Validation errors

Some systems (such as GitHub) use HTTP Status code 422 to indicate validation errors, although you could argue this is reserved for WebDAV.

A discussion of error techniques is here.
There is a draft IETF paper for errors.

Consider multiple validation errors; in this case it is ideal to return a collection of errors. See Twitter's API.

HATEAOS

A great example of how a single REST URI can be used to navigate around application state is shown in the Starbucks example. Perfoming a POST (Create) of a resource returns the possible actions that may be performed thereafter.

Example APIs

Netflix
Twitter
Klarna Checkout
PayPal