API Design Guidelines

All good things must come to an api endpoint

Most of the real world application these days work by calling some sort of API to display or process data. API led connectivity has increased the pace of development. It is very similar to putting lego blocks together to build something useful.

With the evolution of API, there are 2 major principles which drives the success

  1. Platform Agnostic: A client should be able to call the API, regardless of how the API is implemented internally. The complexity should be hidden and the contract between the API and the client should define the mechanism of data exchange.

  2. Scalability: An API should be able to scale without independent of client application dependency. The new functionality should be exposed and easily discoverable to the client.


Representational State Transfer API (REST API)

In 2000, Roy Fielding in his dissertation laid the foundation for REST architecture. REST is independent of any underlying protocol and is not necessarily tied to HTTP. However, most common REST implementations use HTTP as the application protocol, and this guide focuses on designing REST APIs for HTTP.

The following outlines designing a REST API for Web Services Architecture.

  1. [API Endpoint] (#api-endpoint)
  2. [Authentication] (#authentication)
  3. [Caching] (#caching)
  4. [HTTP Methods (verbs)] (#http-verbs)
  5. [HTTP Response Codes] (#response-codes)
  6. [Query Parameters] (#query-params)
  7. [Versioning] (#versioning)
  8. [Checklist] (#checklist)

API Endpoint

The endpoint should have following features:

  • It should be friendly to developer and be explored via browser / rest client address bar
  • It should be simple, consistent and intuitive to make adoption easy
  • It should provide flexibility for getting the data as required
  • It should be concrete names because Cool URIs never change.

Authentication

The endpoint should be always authenticated to prevent from automated attacks. There are multiple ways of authenticating an endpoint.

  • Token Based Authorization: In token based authorization, a token should be given to the given along with the call to the endpoint. The token can have the client signature and the expiry time. The service should first validate the token before doing the processing. If the token configuration is invalid, the service should return the error with response code as 401.
  • Key Based Authorization: A key is provided with the request by the client. The key can be unique to each client. This also helps in doing rate-limiting and statistics on the api calls. The key should be validated for the correct client and the expiration before the processing. If invalidated, the service should return the error with response code as 401.

Caching

A parameter should be given with the API definition to set / unset cache. The response for subsequent calls to the same resource should be based on the cache parameter. Default value for the parameter to be set as true. This helps in reducing the response time and also results in better performance.

The table below describes the expiry for cache.

ExpiryDescription
x minsIf external or third-party services is used
< x minsIf the values fetched doesn’t change frequently
(where x is defined as per requirement)

HTTP Methods (verbs)

The following table explains the usage of HTTP verbs

HTTP VerbDescriptionExample
getFor retrieval/test-service/test-resource/<resourceId>
postFor persistance
Request ParamsValues
Headersapplication/json
application/xml
Bodyjson_content
xml_content
AuthorizationToken
API_KEY
putFor updating
{For updating the complete object}
/test-service/test-resource/<resourceID>
Request ParamsValues
Headersapplication/json
application/xml
Bodyjson_content
xml_content
AuthorizationToken
API_KEY
patchFor partial updating/test-service/test-resource/<resourceID>
Request ParamsValues
Headersapplication/json
application/xml
Bodyjson_content
xml_content
AuthorizationToken
API_KEY
deleteFor deleting/test-service/test-resource/<resourceID>
Request ParamsValues
Headersapplication/json
application/xml
Bodyjson_content
xml_content
AuthorizationToken
API_KEY

HTTP Response Codes

Only standard response codes should be used for the services. The list below defines the allowed status codes

Response CodeDescription
200For successful execution of request
201For successful creation of the new instance of object as in the request
204For successful processing of request. Should be used for delete requests
400Bad request. Because of invalid body or headers
401Unauthorized. Invalid authorization token
404Not Found. Resource not found
500Internal Server Error

Query Parameters

Query parameters can be used for following operations.

OperationDescription
PagingRequired if the data returned by the service is more than 25 records at a time
FilteringRequired if data is to be filtered based on arguments.
Example: /test-service/test-resource?resourceFilter=test1
SortingRequired if data is to be sorted in a particular order.
Example: /test-service/test-resource?startDate=2016-01-1&endDate=2017-01-01
SearchingRequired if data is to be retrieved based on query parameters but supports approximate matching

Versioning

It’s always advisable to version the APIs. This helps in maintaining code independence and new changes are introduced without breaking current functionality. There are various approaches to version the API.

  • In URL:

    API can be versioned by appending the version number in the resource URL.
    Example: /v1.0/ test-service

  • In Header:

    Some users prefer version number to be passed in the headers when calling the API
    Example: /test-service HEADER: version: 1.0

  • As query parameter: API are also versioned by passing version number in the resource URL but as query parameter.
    Example: /test-service?version=1.0


Checklist

This is a personal checklist which I use to review the code for APIs.

  1. HTTP Verbs are used for what they are defined as above. For example: A POST request should not do a partial update on the resource.

  2. URI formatting

    1. Use plurals when returning collections in response.
      Example: test-service/test-resources will return all resources related to the account.

    2. URI should not have trailing slash at the end of it
      Example:

      URI StructureAllowed
      /test-service/test-resource/<resourceID>/wrong
      /test-service/test-resource/<resourceID>correct
    3. URI for every endpoint uses nouns instead of verbs.
      Example:

      URI StructureAllowed
      get
      /test-service/gettestResource/<resourceID>
      wrong
      post
      /saveDocuments
      wrong
      get
      /test-service/test-resource/<resourceID>
      correct
      post
      /documents
      correct
  3. All messages are defined for HTTP response codes associated with the request.
    Example: Always define 200, 400 and 500 responses.

  4. Always define Content-Type header to explicit say about the responses.

  5. Cache is used if possible

  6. Don’t expose underlying data model in response. Only return what is required or is business need.


### References:

For further reading I would like to suggest an article in Microsoft’s technical documentation. Microsoft API Guidelines

comments powered by Disqus