Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sinatra and Grape API together?

I've been reading around and I found this micro-framework called Grape for ruby. I am currently using Sinatra to handle the web interface but I would also like to implement Grape to handle the API aspect of the app. I can't find any helpful suggestions to this topic. The grape documentation says "Grape is a REST-like API micro-framework for Ruby. It's designed to run on Rack or complement existing web application frameworks such as Rails and Sinatra by providing a simple DSL to easily develop RESTful APIs." So it sounds like there should be an official way of combining both right? This app will also be run on Heroku.

like image 740
Cristian Rivera Avatar asked Feb 27 '13 00:02

Cristian Rivera


1 Answers

The phrases you're looking for are:

  • multiple rack apps
  • rack middleware
  • mapping urls rack sinatra

That kind of thing. Grape, Sinatra and Rails are all Rack apps. What this means is that you can build your Grape app, your Sinatra app, and your Rails app, and then you can use Rack to run them as they're all Rack compliant because they share an interface.

What this means in practice is you write the applications, and then you put them in a rackup file to run them. A short example using 2 Sinatra apps (but they could be any number of any kind of Rack apps) :

# app/frontend.rb
require 'sinatra/base'
# This is a rack app.
class Frontend < Sinatra::Base
  get "/"
    haml :index
  end
end

__END__

@@ layout
%html
  = yield

@@ index
%div.title This is the frontend.


# app/api.rb
# This is also a rack app.
class API < Sinatra::Base

  # when this is mapped below,
  # it will mean it gets called via "/api/"
  get "/" do
    "This is the API"
  end
end

# config.ru
require_relative "./app/frontend.rb"
require_relative "./app/api.rb"

# Here base URL's are mapped to rack apps.
run Rack::URLMap.new("/" => Frontend.new, 
                     "/api" => Api.new) 

If you wanted to add the Twitter API example from the Grape README:

# app/twitter_api.rb
module Twitter
  # more code follows

# config.ru
require_relative "./app/twitter_api.rb" # add this

# change this to:
run Rack::URLMap.new("/" => Frontend, 
                     "/api" => API,
                     "/twitter" => Twitter::API)

Hopefully that's enough to get you started. There are plenty of examples once you know where to look. You can also run other apps inside a Sinatra app by using use (see http://www.sinatrarb.com/intro#Rack%20Middleware) and I see that Grape offers the mount keyword too. There are lots of ways available, which may be a bit confusing at first, but just try them out and see what they do and what you like best. A big part of it is preference, so don't be afraid to go with what feels right. Ruby is for the human more than the computer :)


Edit: A Sinatra app with a Grape app "inside"

class App < Sinatra::Base
  use Twitter::API
  # other stuff…
end

# config.ru
# instead of URLMap…
map "/" do
  run App
end

I believe it will be something like that.

like image 132
ian Avatar answered Nov 13 '22 19:11

ian