Rails API - my simple approach

I have seen people using very different techniques to build API around Rails applications.
I wanted to show what I like to do in my projects. Mostly because it is a very simple
solution and it does not make your models concerned with another responsibility.

Naming

First, I have a problem with the naming around API. I believe we use invalid nomenclature to describe our intentions.
Let’s think about it for a moment. Imagine we have a Customer object
and we need to keep it somewhere between the restarts of our application (not necessarily Rails application).
So what do we do ? We use serialization to store it in a file. May it be binary format, JSON, XML or YAML:

To store the inner state of an object and use it to recreate it later.

But this is not what we usually want to achieve when building APIs. In such case we want to deliver
some data to the consumer of our API. We don’t try to save the state of an object.

Rather I would say, we present it. Therefore I prefer to use the name serialization when the object
is stored and processed by the same application and its inner state is stored. And the name presenter
sounds good to me in cases when you talk about an object with a separate application. When you display it
to others. When you show its, what I would say, external state (if such thing might exist).

You might wanna ask “well, what is the difference”? I shall answer you immediately.

The inner state and external state might often not be the same thing. In our case we store first_name and
last_name separately but our clients might only be interested in full_name. There is no reason to send them
{"first_name":"Robert","last_name":"Pankowecki"} when they actually need: {"full_name":"Robert Pankowecki"}.

So… What shall we do ? Bring up the presenters on stage.

Initial implementation

Presenter, for me, in API requests has a role similar to the View layer in classic requests to obtain HTML page.
We want a layer whose responsibility is to build the response data. And we want it to be separated from our
domain and most likely contain some presentation logic that should not be in model.

Presenters might have logic

Let’s say that the consumers of the API would like to display the avatar of Customer. We know the
email of a customer so we might compute Gravatar url and give it the consumer. We might be tempted
to write such logic in our model (and it is not that bad idea) but because it is of no use to our app,
I would prefer to have a method for that in the presenter itself.

Presenters might use multiple objects

Do you like Hypermedia API ? I still don’t know but let’s give it a try here just to prove my point ☺.
There is a feature that customer can be notified about promotions and other events. It is done by
sending request to URL that we have available under customer_notification_url route method in our controller.
We would like to send it also to the API clients of our app.

It doesn’t matter which way you like most. All options are still available to you. You know
how they work and what are the implications of using the solution you have chosen. Because
they are part of the language that you use daily. Not yet another DSL which must implement its
own syntax to let you share some parts of the code and mimic inheritance. Plain, old, simple
Ruby.

Limitations

Nothing of what I showed here will help in the case where you actually need to created objects
based on XML or JSON that you received. Roar might be really helpful in such situation.