RESTful (REpresentational State Transfer)
REST Contraints
Uniform interface
- Resource-Based (e.g. Database, files)
- Identified by URIs (e.g. URL)
- Separate from their representation(s)
- Manipulation of Resources Through Representations
- Representation represent the (partial) state of resource (e.g. HTML, JSON, XML, CSV…)
- The representation that client holds contains enough information to modify or delete the resource on the server if it has permission to do so. (HTTP response body)
- Separate from resource(s)
- Self-descriptive Messages
- Each request contains enough context to process the message(Self-descriptive messages)(e.g. HTTP request with method GET, PUT, POST, DELETE…)
- Hypermedia as the Engine of Application State (HATEOAS)
- Clients deliver state via body contents, query-string parameters, request headers and the requested URI (the resource name).
- Services deliver state to clients via body content, response codes, and response headers.
Stateless
- Server contains no client state
- Any session state is held on the client
Client-server
- Assume a disconnected system
- Separation of concerns
- Clients are not concerned with data storage
- Servers are not concerned with the user interface or user state
- Uniform interface is the link between the two
Cacheable
- Responses must therefore, implicitly or explicitly, define themselves as cacheable, or not, to prevent clients reusing stale or inappropriate data in response to further requests.
- Well-managed caching partially or completely reduce client–server interactions, which improving perfomance.
Layered system
- Client don’t know if there is a caches, proxies, gateways, firewalls behind the server.
Code on demand(Optional)
- Server can temporarily extend client
- Client executes logic (e.g. JavaScript)
REST API Quick Tips
Use HTTP Verbs to Make Your Requests Mean Something
| method | usage |
|---|---|
| GET | Read a specific resource (by an identifier) |
| POST | Create a new resource |
| PUT | Update a specific resource (by an identifier) |
| DELETE | Remove/delete a specific resource by an identifier |
Provide Sensible Resource Names
- Use identifiers in your URLs instead of in the query-string.
- Use
/users/:idrather than/api?type=user&id=12345
- Use
- Leverage the hierarchical nature of the URL to imply structure.
/events/:event_id/attendees/:id/users/:user_id/orders/:id
- Design for your clients, not for your data.
- Resource names should be nouns. Use the HTTP methods to specify the verb portion of the request.
/userswithGETrather than/getUsers
- Use plurals in URL segments to keep your API URIs consistent across all HTTP methods.
- Use
/users/,/users/:user_idrather than/users/,/user/:user_id
- Use
- Avoid using collection verbiage in URLs.
- Use
/customersrather than/customer_list
- Use
- Use lower-case in URL segments, separating words with underscores (
_) or hyphens (-). Some servers ignore case. - Keep URLs as short as possible, with as few segments as makes sense.
Use HTTP Response Codes to Indicate Status
- 2xx Success
- 200 OK The most common code. Used to indicate success.
- 201 CREATED Successful creation occurred.
- Often used for
POSTorPUT - Set the Location header to redirect to newly-created resource.
- Response body content may or may not be present.
- Often used for
- 204 NO CONTENT Indicates success but nothing is in the response body
- Often used for
DELETEorPUT
- Often used for
- 3xx Redirects
- 304 NOT MODIFIED Just use cache
- 4xx Client Error
- 400 BAD REQUEST Error code for when fulfilling the request would cause an invalid state.
- Domain validation errors, missing data
- 401 UNAUTHORIZED Error code response for missing or invalid authentication token.
- 403 FORBIDDEN Error code for when the user is not authorized to perform the operation or the resource is unavailable for some reason.
- 404 NOT FOUND Used when the requested resource is not found or doesn’t exist
- If there was a 401 or 403 that, for security reasons, the service wants to mask.
- 405 METHOD NOT ALLOWED Used to indicate that the requested URL exists, but the requested HTTP method is not applicable.
- The Allow HTTP header must be set when returning a 405 to indicate the HTTP methods that are supported(e.g.”Allow: GET, POST, HEAD”).
- 409 CONFLICT Whenever a resource conflict would be caused by fulfilling the request. Duplicate entries, such as trying to create two customers with the same information, and deleting root objects when cascade-delete is not supported are a couple of examples.
- 400 BAD REQUEST Error code for when fulfilling the request would cause an invalid state.
- 5xx Server Error
- 500 INTERNAL SERVER ERROR For errors that the consumer cannot address from their end.
- Never return this intentionally. The general catch-all error when the server-side throws an exception.
- 500 INTERNAL SERVER ERROR For errors that the consumer cannot address from their end.
Offer different format
Let consumers switch between formats using the HTTP Accept header, or by just changing an extension.
/users/:id(.format)
Create Fine-Grained Resources
It’s much easier to create larger resources from individual resources than it is to create fine-grained or individual resources from larger aggregates. As a result, start with small, easily defined resources, providing CRUD functionality on those. And create those use-case-oriented, chattiness-reducing resources later.
Consider Connectedness
APIs become more self-descriptive and discoverable when links are returned in the response. For collections returned in a response that support pagination, ‘first’, ‘last’, ‘next’ and ‘prev’ links at a minimum are very helpful.
Example
| method | URL | CRUD | Action | Response |
|---|---|---|---|---|
| GET | /users(.:format) | Read | all users page | 200 |
| GET | /users/new(.:format) | Read | create user page | 200 |
| GET | /users/:id/edit(.:format) | Read | edit user page | 200 |
| POST | /users(.:format) | Create | Create a new user | 201 |
| GET | /users/:id(.:format) | Read | Retrieve a specfic user | 200|404 |
| PUT | /users/:id(.:format) | Update | Replace a specfic user | 200|204|404 |
| PATCH | /users/:id(.:format) | Update | Modify a specfic user | 200|204|404 |
| DELETE | /users/:id(.:format) | Delete | Destroy a specfic user | 200|204|404 |