Rest API Guidelines

We use Rest APIs for exposing application interfaces through a web service.
Let's look at few Rest API Guidelines :


1.  Logical Resources

The key principles of REST involve separating your API into logical resources. These resources are manipulated using HTTP requests where the method (GET, POST) has specific meaning.
API should define accessing resource using a Noun and not verb. That makes it only 2 URLs per resource.
E.g.
GET /tickets - Retrieves a list of tickets
GET /tickets/12 - Retrieves a specific ticket.


2.      Use appropriate HTTP methods 

Map Appropriate method to service  based on its operation type.
For example 
Create(C) - POST
Read (R) - GET
Update (U) - PUT for complete update and PATCH for Partial Update
Delete(D) - DELETE for deleting

3.        Plural Endpoint name 

     Endpoint need to be defined as plural and not singular.
So you would have:
GET /tickets to retrieve a list of tickets and not GET /ticket.
This also enables to have both /tickets and /tickets/{ticket_ID} under single controller.

4.        Dealing with relations

Use URLS to depict the relations between resources
For example:
GET /tickets/12/messages - Retrieves list of messages for ticket #12
GET /tickets/12/messages/5 - Retrieves message #5 for ticket #12


5.         Beyond CRUD 

There could be Use cases where action does not fit into crud operation. In such cases, use action=<specific_action> as a query parameter.


6.          Value Objects /Entity 

Do not define entity for a given purpose or service rather use relevant portion of entity E.g. ClientVO, SaveClientVO etc.

7.          Resource Names

The logical resources name should be with respect to the consumer of the API and not our business model (E.g. not Segment but Policy or Certificate).

8.          Documentation 

An API is only as good as its documentation. Have descriptive documentation.


9.         GET – Only for Read

Never ever have an update in GET Method! GET should be used only for read APIs.

10. Use SSL 

Always use SSL and do not redirect non-SSLs to SSL urls instead throw the exception.



11.  Path Params & Query Params

Use Path Params to identify a specific resource or resources.
Example:
GET /cars
GET /cars/{id}
POST /cars

While use Query Parameters to sort/filter/search.
GET /tickets?sort=-priority
GET /tickets?state=closed&sort=-updated_at

12. Aliases for common Queries

If possible, consider building set of conditions into meaningful RESTful paths. For example,
To Query recently closed tickets, we would generally have :
GET /tickets?state=closed&sort=-updated_at
We can enhance the API experience by having following for this :
GET /tickets/recently_closed



13. Updates & creation should return a resource representation


To prevent an API consumer from having to hit the API again for an updated representation, have the API return the updated (or created) representation as part of the response.



14. Use JSON format

Stick with JSON as much as possible unless specific client requirement is for XML format.

15. Field Names 

Use camel case for field names.


16. Rate Limiting

To prevent abuse, it is standard practice to add some sort of rate limiting to an API. 
Following headers need to be included:
· X-Rate-Limit-Limit - The number of allowed requests in the current period
· X-Rate-Limit-Remaining - The number of remaining requests in the current period
· X-Rate-Limit-Reset - The number of seconds left in the current period

17. Pretty & gzip

Make sure API response is pretty print by default and gzip is supported.

18. Caching

HTTP provides a built-in caching framework. There are two approaches :
ETag: When generating a response, include a HTTP header ETag containing a hash or checksum of the representation. This value should change whenever the output representation changes. Now, if an inbound HTTP requests contains a If-None-Match header with a matching ETag value, the API should return a 304 Not Modified status code instead of the output representation of the resource.
Last-Modified: This basically works like to ETag, except that it uses timestamps. The response header Last-Modified contains a timestamp in RFC 1123 format which is validated against If-Modified-Since. 


19.  Friendly URLs

URL should be friendly to the developer and be explorable via a browser address bar

20. Errors

The API should return 400 series HTTP status codes for client issues & 500 series HTTP status code for server issues.

21. Verbose Messages 

Messages returned in the payload should be as verbose as possible.


22. Limiting Fields

Use a fields query parameter that takes a comma separated list of fields to include. For example, the following request would retrieve just enough information to display a sorted listing of open tickets:
GET /tickets?fields=id,subject,customer_name,updated_at&state=open&sort=-updated_at


23. Pagination

Limit the number of records returned in the response. Consumer can use offset, limit params to get specific data. It is a good practice to always return some metadata with each paginated response ( for example, total records size). 

24. HTTP status codes.

The API should always return sensible HTTP status codes. Listed below are commonly used codes :
· 200 OK - Response to a successful GET. Can also be used for a POST that doesn't result in a creation.
· 201 Created - Response to a POST that results in a creation. Should be combined with a Location header pointing to the location of the new resource
· 204 No Content - Response to a successful request that won't be returning a body (like a DELETE request)
· 304 Not Modified - Used when HTTP caching headers are in play
· 400 Bad Request - The request is malformed, such as if the body does not parse
· 401 Unauthorized - When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser
· 403 Forbidden - When authentication succeeded but authenticated user doesn't have access to the resource
· 404 Not Found - When a non-existent resource is requested· 
· 405 Method Not Allowed - When an HTTP method is being requested that isn't allowed for the authenticated user· 
· 410 Gone - Indicates that the resource at this end point is no longer available. Useful as a blanket response for old API versions
· 415 Unsupported Media Type - If incorrect content type was provided as part of the request
· 422 Unprocessable Entity - Used for validation errors
· 429 Too Many Requests - When a request is rejected due to rate limiting

25. Role base access & Security

API should always have an authorization in place to check for role based access to data( based on its sensitivity & confidentiality).
For example,
Let’s say we have an API GET /student/{student_id}
Now , GET /student/12
should be only accessible to a user who belongs to Group/Role that can access the student_id =12( for example, student with student_id=12, administrators etc) and will not be accessible to student with student_id=13 or other users who do not belong to Group/Role.
This could be also applicable to POST requests where authorization check must be carried out ( in addition to default authentication check for POST) to make sure user has appropriate access to make the changes.

26. Versioning

API should always be versioned (not an optional thing). This makes it easy to deal with multiple clients requiring different/customized versions of same API.
There are four ways to version your API; URI versioning, Request Parameter versioning, Custom header versioning & Media Type versioning.
Describe each way of versioning Rest Services: <Coming soon a special blog on this>

27. API Hierarchy 

Consolidate all API under one domain and then build a hierarchy which should be self-explanatory to Consumer of the API.