Rails is missing an abstraction when it comes to building REST APIs, in my opinion. Requests route through controllers, controllers call models or services to obtain the right objects. And then…you awkwardly try to bang a JSON object together with an ERB template? It gets awkward quickly.
There’s a lot of experimentation in the wild attempting to figure out what works well here. You can bang out a bunch of presenter classes. You can describe and compose representations. You can go resource oriented.
I came across one yesterday that immediately caught my eye. You could just use lambda
to implement a bunch of functions that present, decorate, or map objects from one representation to another. To borrow an example:
# Define a base representation
UrlsPresenter = lambda do
{
'self' => "#{Gauges.api_url}/me",
'gauges' => "#{Gauges.api_url}/gauges",
'clients' => "#{Gauges.api_url}/clients",
}
end
# Compose the base representation with more data
UserPresenter = lambda do |user|
{
'id' => user.id,
'email' => user.email,
'name' => user.name,
'urls' => UrlsPresenter.call
}
end
# Pass an object to the presenter and convert it to JSON
UserPresenter[user].to_json
I love that this one adds no machinery and no state. Input, function, output. With just lambda
, you can describe a bunch of transformations and string them together into meaningful and interesting pipelines. I’m experimenting with this now, hoping to find an interesting way that functional programming approaches can make it simpler to build APIs with Rails.