Introduction to RESTful API Design

An Application Programming Interface (API) allows two systems to communicate with one another. An API essentially provides the language and contract for how two systems interact. Each API has documentation and specifications which determine how information can be transferred.

Just like a webpage is rendered, APIs can use HTTP requests to get information from a web application or web server.

APIs are typically categorized as either SOAP or REST and both are used to access web services. SOAP relies solely on XML to provide messaging services, while REST offers a more lightweight method, using URLs in most cases to receive or send information. REST uses different HTTP verbs (GET, POST, PUT, PATCH and DELETE) to perform tasks.

An endpoint is one end of a communication channel. They are important aspects of interacting with server-side web APIs, as they specify where resources lie that can be accessed by third party software. Usually the access is via a URI to which HTTP requests are posted, and from which the response is thus expected.

In the case of OAuth, there are three endpoints you need to be concerned with:

  1. Temporary Credential Request URI (called the Request Token URL in the OAuth 1.0a community spec). This is a URI that you send a request to in order to obtain an unauthorized Request Token from the server / service provider.
  2. Resource Owner Authorization URI (called the User Authorization URL in the OAuth 1.0a community spec). This is a URI that you direct the user to to authorize a Request Token obtained from the Temporary Credential Request URI.
  3. Token Request URI (called the Access Token URL in the OAuth 1.0a community spec). This is a URI that you send a request to in order to exchange an authorized Request Token for an Access Token which can then be used to obtain access to a Protected Resource.

Endpoints need to be static, otherwise the correct functioning of software that interacts with it cannot be guaranteed. If the location of a resource changes (and with it the endpoint) then previously written software will break, as the required resource can no longer be found at the same place. As API providers still want to update their web APIs, many have introduced a versioning system in the URI that points to an endpoint. For example the following URI: “". The “/v1/” part of the URI specifies access to the first version of the web API. If it is decided to update to version two, they can do this while still maintaining support for third party software that uses the first version.

When designing API endpoints, there’s always the need to specify what http method to use for CRUD (Create, Read/Retrieve, Update, Delete) operations. Commonly, this is nailed down as:

  • Create: POST
  • Read/Retrieve: GET
  • Update: PUT/PATCH
  • Delete: DELETE

POST. Use POST APIs to create new subordinate resources, e.g. a file is subordinate to a directory containing it or a row is subordinate to a database table. Talking strictly in terms of REST, POST methods are used to create a new resource into the collection of resources.

Ideally, if a resource has been created on the origin server, the response SHOULD be HTTP response code 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.

Many times, the action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either HTTP response code 200 (OK) or 204 (No Content) is the appropriate response status.

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields.

Please note that POST is neither safe nor idempotent and invoking two identical POST requests will result in two different resources containing the same information (except resource ids).

GET. Use GET requests to retrieve resource representation/information only and not to modify it in any way. As GET requests do not change the state of the resource, these are said to be safe methods. Additionally, GET APIs should be idempotent, which means that making multiple identical requests must produce the same result every time until another API (POST or PUT) has changed the state of the resource on the server.

If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.

For any given HTTP GET API, if the resource is found on the server then it must return HTTP response code 200 (OK) – along with response body which is usually either XML or JSON content (due to their platform independent nature).

In case resource is NOT found on server then it must return HTTP response code 404 (NOT FOUND). Similarly, if it is determined that GET request itself is not correctly formed then server will return HTTP response code 400 (BAD REQUEST).

PUT APIs primarily update an existing resource (if the resource does not exist then API may decide to create a new resource or not). If a new resource has been created by the PUT API, the origin server MUST inform the user agent via the HTTP response code 201 (Created) response and if an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

The difference between the POST and PUT APIs can be observed in request URIs. POST requests are made on resource collections whereas PUT requests are made on an individual resource.

PATCH requests are to make partial update on a resource. PUT requests modify a resource entity so to make it more clear, PATCH method is the correct choice for partially updating an existing resource and PUT should only be used if you’re replacing a resource in its entirety.

However, for simple resource representations, the difference is often not important, and many APIs simply implement PUT as a synonym for PATCH. This usually doesn’t give any problems because it is not very common that you need to set an attribute to null, and if you need to, you can always explicitly include it. For more complex representations, especially including lists, it becomes very important to be able to express accurately the changes you want to make. In these cases provide PATCH and PUT, and make PATCH do an relative update and have PUT replace the entire resource.

DELETE APIs are used to delete resources (identified by the Request-URI). A successful response of DELETE requests SHOULD be HTTP response code 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has been queued, or 204 (No Content) if the action has been performed but the response does not include an entity.

DELETE operations are idempotent. If you DELETE a resource, it’s removed from the collection of resource. Repeatedly calling DELETE API on that resource will not change the outcome — however calling DELETE on a resource a second time will return a 404(Not Found) since it was already removed. Some may argue that it makes DELETE method non-idempotent. It’s a matter of discussion and personal opinion.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.