APIs for data access and management are typically concerned with four actions (the so-called CRUD operations):
- Create - the ability to create a resource
- Read - the ability to retrieve a resource
- Update - the ability to modify a resource
- Delete - the ability to remove a resource
CRUD operations don't have a perfect, 1-to-1 mapping to HTTP methods, which has led to different opinions and implementations, but the following list represents best practice as I see it in the industry today, and follows the HTTP specification:
CRUD Operation | HTTP Method |
Create | POST |
Read | GET |
Update | PUT and/or PATCH |
Delete | DELETE |
- POST - create a resource
- GET - retrieve a resource
- PUT - update a resource (by replacing it with a new version)*
- PATCH - update part of a resource (if available and appropriate)*
- DELETE - remove a resource
Although PATCH is considered the officially correct and "RESTful" way to do partial updates, it has yet to gain wide adoption. Many popular web application frameworks don't support the PATCH method yet, so in practice, it is not uncommon to use PUT for partial updates even though its not strictly "RESTful". The decision to use PUT vs. PATCH for partial updates is driven by the capabilities of your framework of choice (Rails only recently introduced PATCH, for example) and by the practical requirements of building web/mobile back-end services that actually work and are easy to use, even if they don't satisfy REST purists. More on this in the next post.
Safe and Idempotent Methods
The HTTP 1.1 specification defines "safe" and "idempotent" methods [1]. Safe methods don't modify data on the server no matter how many times you call them. Idempotent methods can modify data on the server the first time you call them, but repeating the same call over and over again won't make any difference. Here's a partial list:
Method | Safe | Idempotent |
---|---|---|
GET | ✔ | ✔ |
HEAD | ✔ | ✔ |
PUT | × | ✔ |
PATCH | × | ✔ |
DELETE | × | ✔ |
POST | × | × |
The safe and/or idempotent nature of these HTTP methods provides some further insight into how they ought to be used. Notice that POST is neither safe, nor idempotent. A successful POST should create new data on the server, and repeating the same call should create even more copies on the server. GET, on the other hand, is safe and idempotent, so no matter how many times you call it, the data on the server shouldn't be affected.
GET - use it to fetch resources, but don't "tunnel" request parameters through to the server as a way to alter the state of data on the server - as a "safe" method, calling GET shouldn't have side effects.
PUT - use it to update an existing resource by replacing it with a new representation. The data you PUT to the server should be a complete replacement for the specified resource. Although PUT can in theory be used to insert new resources, in practice it's not advisable. Note that after the first PUT request, repeatedly calling the same PUT method with the same data won't change the data on the server more than it already has been (a condition of idempotent methods).
PATCH - if this method is available and well supported in both your client and server side technology stack (ie. Rails 4), consider using it to update part of an existing resource by changing some of it's properties, following the recommendations of the framework for how to submit the change descriptions. The PATCH method isn't supported everywhere and not common enough to be considered a current best practice, but the industry seems to be moving this way and technically it's the correct way to provide partial updates according to the HTTP spec [2].
If your server, framework or client user base (IE8, etc) doesn't support PATCH, rest assured that many developers take the pragmatic approach and simply bend the rules to use PUT for partial updates [3]. I'll cover this in the next post in more detail. Note that, no matter how you do your partial update, it should be atomic, that is once the update has started, it should not be possible to retrieve a copy of the resource until the update has been fully applied.
POST - use it to create new resources. The server should create a unique identifier for each newly created resource. Return a 201 Created response if the request was successful. The unique ID should be returned in the response; it has been suggested to use the Location header of the response for this, but for most client applications it will be more practical to return the ID in the body of the response. For this reason, best practice currently appears to be to populate both the Location header with the URL of the newly created resource, and also return a representation of the resource in the response body that includes it's id and/or URL. POST is also frequently used to trigger actions on the server which technically aren't part of RESTful API, but provide useful functionality for web applications.
DELETE - use it to delete resources; it's pretty self-explanatory.
More posts in this series
REST API Best Practices 1: A REST Cheat SheetREST API Best Practices 3: Partial Updates - PATCH vs. PUT
REST API Best Practices 4: Collections, Resources and Identifiers
[1] http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
[2] http://stackoverflow.com/questions/19732423/why-isnt-http-put-allowed-to-do-partial-updates-in-a-rest-api
[3] http://techblog.appnexus.com/2012/on-restful-api-standards-just-be-cool-11-rules-for-practical-api-development-part-1-of-2/
1 comment:
Thanks for this set of articles on CRUD.
Post a Comment