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:
  • /books
  • /books/123
  • here in second url, 123 represents a specific book with id ( the resource id) in collection.

    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
  • /media is bad
  • /audio , /video , /book is good
  • Stick to: /resource/id/resource

    Dont define more than 1 level of resource relationship hierarchy.
  • /book/1/author is good
  • 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.
  • /books?pages=2000&cover=hardback
  • 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:
  • 200 - success
  • 400 - Bad request
  • 500 - Internal server error
  • 404 - Not found
  • etc. These codes can help to properly communicate error and thereby making it useful for a developer to understand what type of error has occured and hence a correct error message can be communicated to client.

    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.
  • /v1/books
  • 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.
  • /books?offset=2&limit=10
  • Sorting

    Use a sort parameter. Put a '-' in front of sort parameter to indicate descending sort.
  • /books?sort=-rating
  • Searching

    A search value for global or local search can be indicated by 'q'
  • /book?q=searchparam
  • 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
  • /translate?from=ENG&to=HIN
  • 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

    My favourite API 10/10

  • Github API