Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!

Daniel Doubrovkine (aka dB.) is one of the tallest engineers at Art.sy. He founded and exited a successful Swiss start-up in the 90s, worked for Microsoft Corp. in Redmond, specializing in security and authentication, dabbled in large scale social networking and ran a big team that developed an expensive Enterprise product in NYC. After turning open-source cheerleader a few years ago in the worlds of C++, Java and .NET, he converted himself to Ruby and has been slowly unlearning everything he learned in the last 15 years of software practice. Daniel is a DZone MVB and is not an employee of DZone and has posted 19 posts at DZone. You can read more from them at their website. View Full User Profile

Grape API Mounted on RACK with Static Pages

02.02.2012
Email
Views: 1755
  • submit to reddit

Here’s how I mount a Grape API on Rack and also serve static pages. Most useful for building a service with documentation.

Setup bundler with the required gems. I am using the next version of Grape (frontier branch and the next version of rack-contrib which contains Rack::TryStatic that we’re going to want to use).

    source "http://rubygems.org"
     
    gem "rack", "1.3.5"
    gem "rack-contrib", :git => "https://github.com/rack/rack-contrib.git", :require => "rack/contrib"
    gem "grape", :git => "http://github.com/intridea/grape.git", :branch => "frontier"

Static content goes to a new public folder, for example public/index.html.

Our application will need to boot with all these gems, we’ll do it Rails-style by starting with a config/boot.rb file. It brings in Bundler.

    require 'rubygems'
    require 'bundler/setup'

Lets define our Acme Grape API that will have a system resource that answers ping requests with “pong”. This goes into api/api.rb.

    module Acme
      class API < Grape::API
        version 'v1', :using => :header, :vendor => 'acme', :format => :json    
        resource :system do
          desc "Returns pong."
          get :ping do
            "pong"
          end
        end
      end
    end

The application requires Bundler, all the gems in Gemfile and our API. Lets define it in config/application.rb.

    require File.expand_path('../boot', __FILE__)
     
    Bundler.require :default, ENV['RACK_ENV']
     
    require File.expand_path('../../api/api', __FILE__)



Note the odd File.expand_path construct, borrowed from Rails, - it translates a relative path to the current file into an absolute path, there’re allowing us to run the application from any directory – useful for hosting where you never know who boots the application.

Continuing to borrow from Rails, we will want different environments (development, production, etc.), so it’s a good idea to keep things organized. Setup the environment in config/environment.rb and then load the application.

    ENV['RACK_ENV'] ||= :test
     
    require File.expand_path('../application', __FILE__)

Finally, we need to “rackup” this whole thing in config.ru. We will use Rack::TryStatic to serve static pages when available and pass through to the Acme API otherwise.

    require File.expand_path('../config/environment', __FILE__)
     
    use Rack::TryStatic,
      :root => File.expand_path('../public', __FILE__),
      :urls => %w[/], :try => ['.html', 'index.html', '/index.html']
     
    run Acme::API

Run the application with bundle exec rackup.

image

Full source on Github.

Article Source: http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages


 

 

 

Tags:
Published at DZone with permission of Daniel Doubrovkine, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)