In the post Designing Your RESTful API Part 1: The Nouns, you learned the importance of resources, request headers, and the request body when you defined your RESTful API. In this post, you will learn about the five or so request verbs and what is send back to the client in the response body and the response status code.
Request Verbs describe what you want to do with the resource. GET and POST are the two most commonly requests used when your browser visits different webpages. The term POST is so popular that it has even invaded common language, where people who know nothing about how the Internet works do know they can “post” something on a friends Facebook wall. There are four and a half very important HTTP verbs that you need to know about. I say “and a half”, because the PATCH verb is very similar to the PUT verb, and two two are often combined by many an API developer. Here are the verbs, and next to them are their associated database call (I’m assuming most people reading this know more about writing to a database than designing an API).
- GET (SELECT): Retrieve a specific Resource from the Server, or a listing of Resources.
- POST (CREATE): Create a new Resource on the Server.
- PUT (UPDATE): Update a Resource on the Server, providing the entire Resource.
- PATCH (UPDATE): Update a Resource on the Server, providing only changed attributes.
- DELETE (DELETE): Remove a Resource from the Server.
Here are two lesser known HTTP verbs:
- HEAD – Retrieve meta data about a Resource, such as a hash of the data or when it was last updated.
- OPTIONS – Retrieve information about what the Consumer is allowed to do with the Resource.
A browser typically issues a GET verb to instruct the endpoint it wants to get data, however there are many other verbs available including things like POST, PUT and DELETE.
There is a best practice that GET requests to an entity URI such as
/Products returns a list of products, possibly matching some criteria that was sent with the request. However, to retrieve a specific product, you would use the product’s ID as part of the resource, for example
/Products/81 would return product with the ID of 81. It is also possible to use query string parameters with an API, for example you may have something like
/Products?color=red which returns all red products.
These are some typical requests you might expect to see in an API:
|Resource||Verb||Expected Outcome||Response Code|
||GET||A list of all products in the system||
||GET||A list of all products in the system where the color is red||
||POST||Creation of a new product||
||GET||Product with ID of 81||
(a product ID which does not exist)
|GET||Some error message||
||PUT||An update to the product with an ID of 81||
||DELETE||Deletion of the product with an ID of 81||
||GET||A list of all customers||
Planning how your API will look begins earlier than you’d think; first you need to decide how your data will be designed and how your core service / application will work. If you’re doing development for the first time, this should be straight forward. If you’re attaching an API to an existing project, you may need to provide more abstraction.
Occasionally, a Collection can represent a database table, and a Resource can represent a row within that table. However, this is not the usual case. In fact, your API should abstract away as much of your data and business logic as possible.
There’s also a proper way to do responses: using the HTTP Response Codes and Reason Phrase.
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace (…) Failure here implies that clients are assuming a resource structure due to out-of-band information (…) A REST API should be entered with no prior knowledge beyond the initial URI. – Roy Thomas Fielding
That means that in a truly REST based architecture any URL, except the initial URL, can be changed, even to other servers, without worrying about the client.
And because anything can be changed, the client should be able to respond to a variety of messages.
1xx – Informational
A client MUST be prepared to accept one or more 1xx status responses prior to a regular response, even if the client does not expect a 100 (Continue) status message. Unexpected 1xx status responses MAY be ignored by a user agent.
2xx – Successful
This class of status code indicates that the client’s request was successfully received, understood, and accepted.
- 200 – OK
- 201 – Created
- 202 – Accepted
- 203 – Non-Authoritative Information
- 204 – No Content
- 205 – Reset Content
- 206 – Partial Content
- 207 – Multi-Status
3xx – Redirection
This class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request.
- 300 – Multiple Choices
- 301 – Moved Permanently
- 302 – Found
- 303 – See Other
- 304 – Not Modified
- 305 – Use Proxy
- 306 – (Reserved)
- 307 – Temporary Redirect
4xx – Client Error
The 4xx class of status code is intended for cases in which the client seems to have erred. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user.
- 400 – Bad Request
- 401 – Unauthorized
- 402 – Payment Required
- 403 – Forbidden
- 404 – Not Found
- 405 – Method Not Allowed
- 406 – Not Acceptable
- 407 – Proxy Authentication
- 408 – Request Timeout
- 409 – Conflict
- 410 – Gone
- 411 – Length Required
- 412 – Precondition Failed
- 413 – Request Entity Too Large
- 414 – Request-URI Too Long
- 415 – Unsupported Media Type
- 416 – Requested Range Not Satisfiable
- 417 – Expectation Failed
- 422 – Unprocessable Entity
- 423 – Locked
- 424 – Failed Dependency
5xx – Server Error
Response status codes beginning with the digit “5” indicate cases in which the server is aware that it has erred or is incapable of performing the request.
- 500 – Internal Server Error
- 501 – Not Implemented
- 502 – Bad Gateway
- 503 – Service Unavailable
- 504 – Gateway Timeout
- 505 – HTTP Version Not Supported
- 507 – Insufficient Storage
Another useful bit of information is what actions can be performed on a given resource. The way to find that out is to use the HTTP request method OPTIONS:
BEST PRACTICE: A 200 response [to an OPTIONS request] SHOULD include any header fields that indicate optional features implemented by the server and applicable to that resource (e.g., Allow), possibly including extensions not defined by this specification.
An error response should consist of the following:
- The appropriate HTTP error status code and any other relevant headers;
- A human readable message in the appropriate format (including a link to the documentation);
- A Link header to a meaningful state transition if appropriate.