Quick Start Guide
This guide will walk you through creating a simple but functional API using Grape. We'll build a small part of a Twitter-like API as an example.
Basic API Structure
Grape APIs are Rack applications that are created by subclassing Grape::API
. Here’s a basic example that demonstrates common features like versioning, formatting, helpers, and resource definition.
Create a file named twitter_api.rb
:
# twitter_api.rb
require 'grape'
# Assume User and Status models exist
# class User; end
# class Status; end
module Twitter
class API < Grape::API
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
helpers do
def current_user
# A real implementation would authenticate the user
@current_user ||= User.new # User.authorize!(env)
end
def authenticate!
# A real implementation would check for a valid session
# error!('401 Unauthorized', 401) unless current_user
end
end
resource :statuses do
desc 'Return a public timeline.'
get :public_timeline do
# Status.limit(20) - Dummy data for now
[{ user: 'user1', text: 'hello' }, { user: 'user2', text: 'world' }]
end
desc 'Return a personal timeline.'
get :home_timeline do
authenticate!
# current_user.statuses.limit(20)
[{ user: 'current_user', text: 'my post' }]
end
desc 'Return a status.'
params do
requires :id, type: Integer, desc: 'Status ID.'
end
route_param :id do
get do
# Status.find(params[:id])
{ id: params[:id], text: "Status ##{params[:id]}" }
end
end
desc 'Create a status.'
params do
requires :status, type: String, desc: 'Your status.'
end
post do
authenticate!
# Status.create!({ user: current_user, text: params[:status] })
{ user: 'current_user', text: params[:status] }
end
desc 'Update a status.'
params do
requires :id, type: String, desc: 'Status ID.'
requires :status, type: String, desc: 'Your status.'
end
put ':id' do
authenticate!
# current_user.statuses.find(params[:id]).update({ user: current_user, text: params[:status] })
{ id: params[:id], text: params[:status] }
end
desc 'Delete a status.'
params do
requires :id, type: String, desc: 'Status ID.'
end
delete ':id' do
authenticate!
# current_user.statuses.find(params[:id]).destroy
{ id: params[:id], status: 'deleted' }
end
end
end
end
Running the API
Since Grape is a Rack application, you can run it with any Rack-compatible server like Puma or Thin. The simplest way is using rackup
.
Create a config.ru
file in the same directory:
# config.ru
require './twitter_api'
run Twitter::API
Now, start the server from your terminal:
$ rackup
Interacting with the API
Your API is now running! It will respond to the following routes:
GET /api/statuses/public_timeline
GET /api/statuses/home_timeline
GET /api/statuses/:id
POST /api/statuses
PUT /api/statuses/:id
DELETE /api/statuses/:id
Here's how you can interact with it using curl
. Note the Accept
header, which is required because we specified using: :header
for versioning.
Get the public timeline:
$ curl -H "Accept: application/vnd.twitter-v1+json" http://localhost:9292/api/statuses/public_timeline
[{"user":"user1","text":"hello"},{"user":"user2","text":"world"}]
Create a new status:
$ curl -X POST -H "Accept: application/vnd.twitter-v1+json" -H "Content-Type: application/json" -d '{"status":"Grape is awesome!"}' http://localhost:9292/api/statuses
{"user":"current_user","text":"Grape is awesome!"}
Congratulations, you've just built and run your first Grape API! To learn more about its features, dive into the Core Concepts.