RESTful API Best Practices

This post covers best practices for building HTTP and RESTful APIs. Let’s start with the terms that we will use mostly:

  • The resource is a information that can be a singleton or a collection. E.g. /companies, /company and /employees are resources. Collections are set of resources, e.g. /companies collection resource is the collection of /company resource. /Company resource is a singleton resource. A resource may contain sub-collections such as /companies/{company_id}/departments and it can be followed by a singleton resource, e.g. /companies/{company_id}/departments/{department_id}.
  • Operations such as patch, put, update, delete, and post can be performed on these resources.
  • URL (Uniform Resource Locator) is a path.

As I always say that remember the rule of two:

  • Always use plural nouns in the API endpoint.
  • if you need to access a single resource, you can always pass the id in the URL.
  • To sum up, one URL for the collection resource and one for a single resource!
    • A collection of resources: /companies
    • A single resource: /companies/1

Prefer Nouns over Verbs when naming resources:

  • /getCompanies => Bad habit!
  • /companies => Good habit!

HTTP Method:

Use HTTP Methods to Operate on your Resources. You can provide CRUD functionality and more using the GET, POST, PUT, PATCH and DELETE HTTP methods.

  • GET for reading resources.
  • POST  (Non-idempotent) or PUT (Idempotent) for creating new resources.
  • PUT and PATCH for updating existing resources.
  • DELETE for deleting existing resources.

Idempotence HTTP requests will result in the same state on the server no matter how many times that same request is executed. The POST is the only non-idempotent method since it results in a new state every time!

GET:

  • Idempotent since never changes the state of the resource.
  • GET /companies => returns list of companies.
  • GET /companies/1 => returns details of company 1.

POST

  • Non-idempotent since always changes the state of the resource.
  • POST /companies => creates a new company (/company/2).
  • POST /companies => creates another company (/company/3).

PUT

  • Idempotent since never changes the state of the resource. It has upsert functionality so it can be used for creating and updating a resource.
  • PUT cannot be used for partial updates.
  • PUT /companies/2 => updates the company 2 (/company/2).
  • PUT /companies/3/departments => Either creates a department or updates it.

PATCH

  • Idempotent since never changes the state of the resource and it should be used for partial updates.
  • PUT /companies/2 => updates partially the company 2 (/company/2).

DELETE

  • Idempotent since never changes the state of the resource.
  • DELETE /companies/1 => deletes the company 1.

HTTP STATUS CODES:

Always use a suitable HTTP status response code (HTTP Status Codes).

  • 2xx: Success
  • 3xx: Redirect
  • 4xx: Client Error
  • 5xx: Server Error

Searching, sorting, filtering, and pagination

Use the Query String for optional and complex parameters such as searching, sorting, filtering and pagination:

  • GET /companies?company=Google
  • GET /companies/1/departments?department=IT&location=Turkey
  • GET /companies?search=ME
  • GET /companies?sort=rank_asc
  • GET /companies?id=1,2,3
  • GET /companies?page=23

Name Convention

Don’t use underscores (not_good) or capitalize (NotGoodToo). Remember that your RESTful web service will be consumed by a client written in javascript (most probably) so it’s a good idea to stick to the JavaScript convention.

Versioning and HATEOS

It is the best practice to provide links for navigating through REST API so the client can follow.  You should always think about a strategy on how to version your RESTFUL API. Versioning must be considered when the servers are unable to maintain compatibility

There are many different approaches to API versioning. Here are the most popular ones:

  • Most common versioning via URLs:
    • Facebook and Google use the URL versioning
      • /api/v1/companies (Most popular)
      • /api/companies?version=v3
    • Cons:
      • It breaks URLs and not HATEOAS friendly!
      • Not a RESTFUL solution!
    • Pros:
      • Simple and easy to use!
  • Versioning via the Accept HTTP Header:
    • Github implementation is a good example
      • Accept: application/vnd.github.v3+json (Github way)
      • Accept: application/json; version=1
    • Cons:
      • It is hard to notice or understand because you need to give attention to HEADER.
      • You can’t just use URLs to make a call specific version. You have to modify HEADER every time!
    • Pros:
      • It does not hurt URLs since they stay intact!
      • Considered as RESTFul and HATEOAS friendly!

Caching

HTTP provides a built-in caching for you! You can utilize this feature to establish the cache on the client, the server-side, and a proxy server. It is a good practice to avoid implementing caching layer at client-side for following reasons:

  • It could lead to security issues.
  • The client may get slower.

Instead of client-side caching, we can use a forward proxy cache between our client and servers. What are the benefits of it?

  • No development cost.
  • Get benefits of a well-tested and robust caching mechanism.

Basic idea how to use HTTP cache mechanism:

  • Consider setting expiration caching headers for all successful responses of
    • GET request.
    • HEAD request.
  • The post is also cacheable but it is non-idempotent so consider this method as non-cacheable!
  • You should consider adding caching headers to any 3xx (Redirect) and 4xx (Client error) response codes since it will reduce the amount of error traffic from clients.

There are more topics to talk about it! So happy Googling more 🙂

Useful Links:

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.