What is an API?
In its most common usage, we’re referring to the public API of an application. Typically a public API allows anonymous users, or individuals who are not privy to the internal operations of an application, access to some, but not all, kinds of data held by the application, and to give the application a certain subset of commands. If we were working with the Twitter API, we might use it to implement the following features:
- fetch a user’s followers
- favorite a tweet
- block a user from appearing on your timeline
These are all examples of working with a public API. A software company opens its API to the public so that other software developers can build applications that are powered by its service.
Imagine each class in your application as a separate application, a collection of individual little programs sending messages back and forth, asking each other to execute certain commands. This is the perspective most senior developers and those concerned with application architecture take towards the code. At this scale, we refer to the public methods of a class as that class’s API. This view can help us identify the seams between different classes, where one class’s responsibilities end and another’s begin.
Ask “What does the user want to do?”
One of the more common failure of APIs is to simply expose the inner workings of models or controllers. Often this leads forcing users to understand the inner complexities, tangled dependencies, and specialized terminology of your particular application.
We can avoid this problem by asking from the very first, “What does the user want to do?” By putting ourselves into their shoes, working to question the assumptions and vocabulary of our audience, we can craft friendly, usable APIs that can lead to more interesting implementations than APIs that are artificially limiting their use cases through poor design.
Building Your API
Although its not 100% obvious, your Rails application is already an API. One application — your web browser — makes a request for some information. Rails generates a response that consists of HTML, and sends that data back to the browser. Its the browser that handles all the rendering and layout business.
Typically, our Rails APIs will strive to be RESTful, and return data formated as JSON. There are other valid formats, of course – XML is common in some use cases – but we’ll be focusing on JSON for this.
Let’s take a look at this with band_practice demo app. From the command line, we’ll use curl to fetch the
#show action for the Singles controller:
Here’s the result in our log:
Now let’s make the same request, but append
.json to the the URL.
Here’s the result in our log for the JSON request:
Rendering HTML, JSON, and XML
Adding the ability to render different response formats is a simple thing to add to our controller. We accomplish this by using the
1 2 3 4 5 6 7 8 9 10 11 12 13
respond_to passes a format object to the block, to which we assign various rendering options. Notice that we don’t have to do anything for HTML, as Rails automatically knows to render the default template, however we could specify different behavior if we had a reason to.
We’re using the
render function to define what our response will look like. It is aware of a wide range of formats. When you pass it the key :json, it will call #to_json on the value, in this case our hash of specific attributes from the
@single object. We could have simply passed it the
@single object itself, like so:
1 2 3 4 5
Doing so would have transformed the object into a JSON hash, with attribute names as the keys and the value of the attributes as the values in the JSON.
We’ve built a simple API that responds with some data. We could let the consumer of our API parse that data to figure out if their request was successful or if there was an error of some sort, but that seems like cumbersome for them. Instead, we can use HTTP status codes to provide a quick and easy way for our API’s users to see the status of their request.
To set status code in your controller, just pass
:status to our render method.
1 2 3 4 5
Notice in the example above, I used both
:success as well as the official numeric value of 200 to inform the consumer that the request was a success. I tend to use the built-in Rails symbols for this, as they’re more explicit, however its good to know at least the most common HTTP status codes.
- 200 – :ok
- 204 – :no_content
- 301 – :moved_permanently
- 400 – :bad_request
- 403 – :forbidden
- 401 – :unauthorized
- 404 – :not_found
- 410 – :gone
- 422 – :unprocessable_entity
- 500 – :internal_server_error
Just like that, we’ve built a very simple API. Naturally, it can get quite a bit more complicated, but this is basically all there is to it. See the resources listed below for further details.