Pragmatic REST
In this post I'll be reflecting upon writing nice, clean, slick RESTful APIs. Today in this web ecosystem, APIs have become a language for communication. REST has become language of developers to understand, interprete and write a web API. Writing RESTful API is a concept and hence a bit difficult to understand and implement. Since its potrays, reflects a design of a system, the more clean, precise, expressive, the more easier it is to understand and use.
APIs create a base for various business integrations. APIs reflect business model. APIs reflect 'UI of business'.
RESTful web APIs work around resources in a system. You might probably need to go through understanding of 'what is REST'. For eg: A user can be identified as a resource, A vehicle is a resource. I will be considering a 'book' as a resource, around which the API will be designed.
Following are the best practices for designing and writing a RESTful web API.
Keep the url simple.
Two base urls for a resource is more than sufficient. For eg:
Use nouns. No verbs in url
Do not use verb for operations on resource like
/getBook, /getAllBooks, /findBookWithTwoAuthors
Use HTTP verbs
Use HTTP verbs: GET, PUT, POST, DELETE. to operate on resource(s). For eg:- /books : To create(POST) book, To fetch(GET) books list, To update(PUT) books, To delete(DELETE) books
- /book/123 : To create(POST) book, To fetch(GET) book with id 123, To update(PUT) book with id 123, To partially update(PATCH) book, To delete(DELETE) book with id 123
/book or /books, plural or singular?
Make sure to stick to one and dont mix both across API.
Dont be abstract. Identify resources at most granular level.
Dont generalize your resources, for example media resources like audio, video, book
Stick to: /resource/id/resource
Dont define more than 1 level of resource relationship hierarchy.
Filter your resource(s) with ?
To get books based on books attribute like totalpages, cover etc use ? and define the attributes as filters to fetch books.
Error handling
Well not everything right happens in an API. So exceptions are equally important to be communicated. Do not generalize exceptions under one umbrella. Explicitly communicate the exception in the API response body as a message.
Use HTTP status codes
Error can be a client error or server error. Use HTTP codes to define them:
JSON is in, XML is old
Use camelCase for attributes in json response
Versioning
Specify version with a 'v'prefix and an integral number to the url base.
Pagination
It is bad to fetch all records in one go. Therefore the best way to fetch records is in pages or chunks. There are many ways to define pagination. For eg: offset and limit, page and record per page, start and count. The best suit is possibly offset and limit as it is very well understood.
Sorting
Use a sort parameter. Put a '-' in front of sort parameter to indicate descending sort.
Searching
A search value for global or local search can be indicated by 'q'
Partial Response
Partial response is helpful when response is huge and you dont want each detail of a resource. It is helpful in utilizing bandwidth.
GZIP - Compress your response
This can help utilize bandwidth
no resource situation
In such situations there may not exist any resource around which api can be written. Use verbs in such situation For eg: translating a word from one language to another
Authentication
OAuth2.0 to the rescue!
Authorization
Authorization cannot be handled by API. It can only be handled at service layer.
Use HTTP headers wisely
In case of overriding HTTP method, caching, CORS, rate limiting.
Use HTTPS
Validate input at server
Using API key
This is can perhaps be used to identify/authenticate origin of request. It is generally used for commercial APIs.
Document your API