SlideShare a Scribd company logo
The Grapes of Rapid
Michael Bleigh, RubyConf 2010
@mbleigh
@intridea
confask.heroku.com
This is not the
talk I wanted.
CDD
Conference
Driven
Development
Deliver
Promise
Me
Motivation
Ruby makes
hard things easy
But APIs still
aren’t easy
APIs in Rails are
too entangled
APIs in Sinatra
are too manual
Why can’t APIs
have their own
framework?
#newtwitter
Grape
Generalized
Rapid
API
Erector
Something that
sounds like API...
ape grapegravy
High Level
Built for ease of
development.
Sinatra-inspired.
Just works.
What does it do?
What does it
do now?
Basics
require 'grape'
class MyAPI < Grape::API
get 'hello' do
{:hello => 'world'}
end
end
GET /hello
{“hello”:”world”}
JSON
Serialization
•Look for #serializable_hash
•Look for #to_json
•Then tries to encode the object directly
•Other formats coming soon
With Returned Value...
Prefixing
class MyAPI < Grape::API
prefix 'api'
get 'hello' do
{:hello => 'world'}
end
end
GET /hello
404 Not Found
GET /api/hello
{“hello”:”world”}
Versioning
class MyAPI < Grape::API
prefix 'api'
version 'v1'
get 'hello' do
{:version => version}
end
end
GET /api/v1/hello
{“version”:”v1”}
GET /api/v2/hello
404 API Version
Not Found
Namespacing
class MyAPI < Grape::API
namespace :admin do
namespace 'metrics' do
get do
{:clicks => Click.count}
end
get '/:date' do
{:clicks => Click.for_date(params[:date]).count}
end
end
end
end
GET /admin/metrics
{“clicks”:235343}
GET /admin/metrics/2010-11-13
{“clicks”:5392}
Stackable
Configuration
Basic Auth
class MyAPI < Grape::API
get 'open' do
"Hello."
end
namespace :admin do
http_basic do |u,p|
u == 'admin' && p == ENV['ADMIN_PASSWORD']
end
namespace 'metrics' do
get do
{:clicks => Click.count}
end
end
end
end
GET /admin/metrics
401 Unauthorized
admin:somepassword
GET /admin/metrics
{“clicks”:235343}
Helpers
class MyAPI < Grape::API
helpers do
def current_user
User.find_by_token(params[:token])
end
end
get '/me' do
current_user
end
end
GET /me?token=12ab312df
{“screen_name”:”mbleigh”}
Erroring
class MyAPI < Grape::API
helpers do
def current_user
@current_user ||= User.find_by_token(params[:token])
end
end
get '/me' do
error!("401 Unauthorized", 401) unless current_user
current_user
end
end
GET /me?token=invalidtoken
401 Unauthorized
What will
it do soon?
Documentation
Generation
Content
Negotiation
OAuth 1.0/2.0
Multiple Files
Plugin System
Vaporware
Streaming APIs
PubSubHubBub
Presenters
Rate Limiting
Internal API
ConfAsk:
Grape In Action
Questions?
gem install grape
github.com/intridea/grape

More Related Content

The Grapes of Rapid (RubyConf 2010)