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
--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.
We use a few gems that make our lives easier when writing APIs:
* Simplifies the code in controllers, e.g.
render json: resource, status: 200
render error: errors, status: 422
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.
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.
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.
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
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:
200 OK- request has succeeded
201 Created- new resource has been created
204 No Content- no content needs to be returned (e.g. when deleting a resource)
Client error codes
400 Bad Request- request is malformed in some way (e.g. wrong formatting of JSON)
401 Unauthorized- authentication failed
403 Forbidden- user does not have permissions for the resource
404 Not Found- resource could not be found
422 Unprocessable Entity- resource hasn't be saved (e.g. validations on the resource failed)
Server error codes
500 Internal Server Error- something exploded in your application
There are many more HTTP status codes, to read the whole specification you can go here