REST-based service design, v2
Series [ REST-Based Service Design ] Tags [ CRUD, REST API ]
I want to revisit the basic “favorite food” service from last post, in light of some further discussion I’ve had with colleagues.
http://host/path/{userid}/favorites
- GET: returns a list of the user’s favorite foods, in some
representation. Returns 404
NOT FOUND
if the user has never specified favorites. - PUT: sets the list of the user’s favorite foods to be the value sent, creating it if necessary.
- DELETE: removes the user’s favorite list. This is different than doing a PUT with an empty list.
- POST: returns
405 METHOD NOT ALLOWED
.
- GET: returns a list of the user’s favorite foods, in some
representation. Returns 404
http://host/path/{userid}/favorites/{food}
- GET: returns 200 OK if the food is a favorite of the user. Returns 404 NOT FOUND if the food is not a favorite of the user.
- PUT: makes the food one of the user’s favorites
- DELETE: makes the food not a favorite
- POST: returns
405 METHOD NOT ALLOWED
So, PUT
can create a resource if it doesn’t exist, and DELETE
of a URI
means the next GET
of it (in the absence of any other operations) will
be a 404 NOT FOUND
.
One note is that as a client of this API, I want and can make use of the most atomic operation available. For example, to make “spaghetti” a favorite food, I could either:
GET http://host/path/{userid}/favorites
PUT http://host/path/{userid}/favorites
(new list with spaghetti added in)
or I could just:
PUT http://host/path/{userid}/favorites/spaghetti
Note that in the first case, I might have an atomicity issue in the presence of concurrent access, so I might need to build in some sort of optimistic locking protocol, where the representation of the favorites list has a version number on it that is checked by the PUT operation. However, if I just use the second method, I don’t have this issue, because the server handles all my concurrency/transactional stuff for me.