Building an API

Intro

Building an API is different than building a regular HTML application. There are no HTML views to worry about, but instead you should take extra care about response statuses, response format and especially documentation since your application will be used by other developers.

Creating an application

To generate a Rails application with only the elements necessary for an API application use the --api flag e.g. rails new my_application --api

Use the --api flag only if you're sure that your application will exclusively be an API - if you'll have an admin backend or you'll use the view layer in some capacity, the rails API mode will not suffice and it's best to use the standard rails new command.

We write our APIs using the JSON format, more specifically we use the JSON API standard. This allows those who consume our APIs to know what to expect regarding the document structure and they can use libraries which enable them to build their clients faster and easier.

Gems

We use a few gems that make our lives easier when writing APIs:

jsonapiresponders * Simplifies the code in controllers, e.g. if resource.valid? render json: resource, status: 200 else render error: errors, status: 422 end becomes respond_with resource

jsonapi-rails * Takes care of serialization/deserialization of Ruby objects into/out of JSON objects, all according to the JSON API standard, so you don't have to think about those details.

rspec * Testing is always important when building software, but doubly so when writing an API since we can use tests to generate documentation.

dox * Generates documentation from rspec tests in api blueprint format.

Documentation

You can generate documentation from your controller or request specs, and it's very important that you cover all the possible cases and return codes e.g. a valid response, response when there are errors and any other outcome of the action. Also document pagination, enumerations, filtering parameters, sorting parameters and anything else that may be used to refine the results of the API call.

Take special care to document crucial parts of your API like authentication and session management.

Documentation generation should be a part of the Continuous Integration process, so that you can be sure your documentation is always up to date. You can use a service like apiary to host the documentation.

Versioning

APIs must be versioned from the start, that way in case of large changes clients can still use the older version of the API while adjusting their application to the new API specification. Otherwise if the API is not versioned, changes to the API would break clients applications frequently and the client would have to take a lot of care in tracking the changes.

Namespace different API versions in the URL e.g. api/v1/resource where the new version would look like api/v2/resource, and make sure that your application code e.g. your controllers, serializers, tests and documentation are also namespaced.

Pagination

It's often possible that the results of the API call are huge e.g. hundreds of thousands of records, and that's impractical if the client only needs a small part of the results. That's why we can limit the amount of results returned with pagination, which allows the client to choose which part of the results they want to see in the request e.g results 500-600 out of 10000.

Pagination is required for every index action, and should be described in the documentation with information like which query parameters are used, what the default and max page size is, etc.

HTTP headers and status codes

In case the JSON API standard is used clients must set the content-type to application/vnd.api+json in their request headers. Otherwise when using the JSON format application/json will suffice.

Some of the more commonly used HTTP status codes are:

Success codes

Client error codes

Server error codes

There are many more HTTP status codes, to read the whole specification you can go here