Last Updated: February 25, 2016
·
6.36K
· colinm

Make a painless web API in Ruby

Sure, you can implement an API many ways, including some very painful ones involving nothing but base Rails functionality.

But why do any of that when you can enjoy crafting your API?

Grape provides an easy-to-write, easy-to-read DSL for creating non-REST, REST-ish, or REST APIs, even including painless versioning. If you're using Ruby for your main application, your Grape API can easily be mounted alongside or inside any Rack application (including Rails apps).

Need a useless API to return the epoch time? Too easy:

module TickTock
  class API < Grape::API
    version 'v1', using: :path
    format :json

    get "epoch" do
      Time.now.to_i
    end
  end
end

Mounted within Rails, it's even a snap to puke out your ActiveRecord objects:

class QuoteAPI < Grape::API

  # ...

  resource :quotes do
    get :random do
      Quote.find_random
    end
  end

  # ...

end  

Et voila, JSON:

{
  "id": "42",
  "uid": "92cfceb39d57d914ed8b14d0e37643de0797ae56",
  "text": "There is nothing to fear but bears on skates.",
  "author": "Oscar Wilde",
  "truthiness": "true",
  "year": "2013"
}

"But wait," you may be saying, "my object model is full of data I don't want to expose!" This too is easy to deal with (in several flavors, no less). Grape offers an optional plugin to define Entities—that is, the data you want to expose, and (optionally) any transmogrification it needs to undergo to be presentable. Let's say we don't want to reveal that some quotes are fake, or the fact they may have been written a century after the supposed author died. And let's say we've standardized on using the UID for all API access.

We can simply embed an entity definition in our model class:

class Quote < ActiveRecord::Base

  # ...

  class Entity < Grape::Entity
    expose :uid, :text, :author
  end

end

And blammo:

{
  "uid": "92cfceb39d57d914ed8b14d0e37643de0797ae56",
  "text": "There is nothing to fear but bears on skates.",
  "author": "Oscar Wilde"
}

Not HATEOASy enough for your tastes? It's easy enough to implement HATEOAS ideas using Grape alone, but you can also work smarter and extend its capabilities with Roar or other hypermedia presenters.

Grape has a simple DSL, wide compatibility with add-ons, and is easily extensible. Give it a shot for your next API project; you may find building an awesome, forward-and-backward-compatible API is much easier than you ever expected.

2 Responses
Add your response

Grape is good. Grape in combination with Swagger is even better. To generate automatic docs. https://github.com/tim-vandecasteele/grape-swagger

over 1 year ago ·

In my solution I have to do the following:

users = CloudUser.all
present :data, users, :with => CloudUser::Entity

After defining:

class CloudUser < ActiveRecord::Base
    self.primary_key = :username

    has_many :configurations, :class_name => 'Configuration'
    has_many :favorites, :class_name => 'Favorite', :foreign_key => :username

    class Entity < Grape::Entity
      expose :username, :email, :first_name, :last_name
    end
end

So it wasn't as easy as just defining a class Entity for me.

over 1 year ago ·