├── .gitignore ├── .rspec ├── .rubocop.yml ├── .rubocop_todo.yml ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── Procfile ├── README.md ├── Rakefile ├── api └── ping.rb ├── app.rb ├── app ├── acme_app.rb └── api.rb ├── config ├── application.rb ├── boot.rb └── environment.rb └── spec ├── api └── ping_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | log 3 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format=documentation 3 | 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | Exclude: 3 | - vendor/**/* 4 | 5 | Metrics: 6 | Enabled: false 7 | 8 | Metrics/LineLength: 9 | Max: 512 10 | 11 | Style/Documentation: 12 | Enabled: false 13 | 14 | Style/FrozenStringLiteralComment: 15 | Enabled: false 16 | 17 | Naming/MethodName: 18 | Enabled: false 19 | 20 | inherit_from: .rubocop_todo.yml 21 | 22 | inherit_from: .rubocop_todo.yml 23 | 24 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2018-11-03 15:41:01 -0400 using RuboCop version 0.60.0. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | rvm: 4 | - 2.5.3 5 | 6 | language: ruby 7 | 8 | cache: bundler 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | ruby '2.5.3' 4 | 5 | gem 'goliath' 6 | gem 'grape' 7 | gem 'rack-contrib', '~> 1.4.0' 8 | 9 | group :development do 10 | gem 'rake' 11 | gem 'rubocop' 12 | end 13 | 14 | group :test do 15 | gem 'em-http-request' 16 | gem 'rack-test' 17 | gem 'rspec' 18 | end 19 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (5.2.1) 5 | concurrent-ruby (~> 1.0, >= 1.0.2) 6 | i18n (>= 0.7, < 2) 7 | minitest (~> 5.1) 8 | tzinfo (~> 1.1) 9 | addressable (2.5.2) 10 | public_suffix (>= 2.0.2, < 4.0) 11 | ast (2.4.0) 12 | async-rack (0.5.1) 13 | rack (~> 1.1) 14 | axiom-types (0.1.1) 15 | descendants_tracker (~> 0.0.4) 16 | ice_nine (~> 0.11.0) 17 | thread_safe (~> 0.3, >= 0.3.1) 18 | builder (3.2.3) 19 | coercible (1.0.0) 20 | descendants_tracker (~> 0.0.1) 21 | concurrent-ruby (1.0.5) 22 | cookiejar (0.3.0) 23 | descendants_tracker (0.0.4) 24 | thread_safe (~> 0.3, >= 0.3.1) 25 | diff-lcs (1.3) 26 | einhorn (0.7.4) 27 | em-http-request (1.1.3) 28 | addressable (>= 2.3.4) 29 | cookiejar (<= 0.3.0) 30 | em-socksify (>= 0.3) 31 | eventmachine (>= 1.0.3) 32 | http_parser.rb (>= 0.6.0) 33 | em-socksify (0.3.1) 34 | eventmachine (>= 1.0.0.beta.4) 35 | em-synchrony (1.0.6) 36 | eventmachine (>= 1.0.0.beta.1) 37 | em-websocket (0.3.8) 38 | addressable (>= 2.1.1) 39 | eventmachine (>= 0.12.9) 40 | equalizer (0.0.11) 41 | eventmachine (1.0.9.1) 42 | git-version-bump (0.15.1) 43 | goliath (1.0.6) 44 | async-rack 45 | einhorn 46 | em-synchrony (>= 1.0.0) 47 | em-websocket (= 0.3.8) 48 | eventmachine (>= 1.0.0.beta.4) 49 | http_parser.rb (>= 0.6.0) 50 | log4r 51 | multi_json 52 | rack (>= 1.2.2) 53 | rack-contrib 54 | rack-respond_to 55 | grape (1.1.0) 56 | activesupport 57 | builder 58 | mustermann-grape (~> 1.0.0) 59 | rack (>= 1.3.0) 60 | rack-accept 61 | virtus (>= 1.0.0) 62 | http_parser.rb (0.6.0) 63 | i18n (1.1.1) 64 | concurrent-ruby (~> 1.0) 65 | ice_nine (0.11.2) 66 | jaro_winkler (1.5.1) 67 | log4r (1.1.10) 68 | minitest (5.11.3) 69 | multi_json (1.13.1) 70 | mustermann (1.0.3) 71 | mustermann-grape (1.0.0) 72 | mustermann (~> 1.0.0) 73 | parallel (1.12.1) 74 | parser (2.5.3.0) 75 | ast (~> 2.4.0) 76 | powerpack (0.1.2) 77 | public_suffix (3.0.3) 78 | rack (1.6.10) 79 | rack-accept (0.4.5) 80 | rack (>= 0.4) 81 | rack-accept-media-types (0.9) 82 | rack-contrib (1.4.0) 83 | git-version-bump (~> 0.15) 84 | rack (~> 1.4) 85 | rack-respond_to (0.9.8) 86 | rack-accept-media-types (>= 0.6) 87 | rack-test (0.6.3) 88 | rack (>= 1.0) 89 | rainbow (3.0.0) 90 | rake (12.3.1) 91 | rspec (3.8.0) 92 | rspec-core (~> 3.8.0) 93 | rspec-expectations (~> 3.8.0) 94 | rspec-mocks (~> 3.8.0) 95 | rspec-core (3.8.0) 96 | rspec-support (~> 3.8.0) 97 | rspec-expectations (3.8.2) 98 | diff-lcs (>= 1.2.0, < 2.0) 99 | rspec-support (~> 3.8.0) 100 | rspec-mocks (3.8.0) 101 | diff-lcs (>= 1.2.0, < 2.0) 102 | rspec-support (~> 3.8.0) 103 | rspec-support (3.8.0) 104 | rubocop (0.60.0) 105 | jaro_winkler (~> 1.5.1) 106 | parallel (~> 1.10) 107 | parser (>= 2.5, != 2.5.1.1) 108 | powerpack (~> 0.1) 109 | rainbow (>= 2.2.2, < 4.0) 110 | ruby-progressbar (~> 1.7) 111 | unicode-display_width (~> 1.4.0) 112 | ruby-progressbar (1.10.0) 113 | thread_safe (0.3.6) 114 | tzinfo (1.2.5) 115 | thread_safe (~> 0.1) 116 | unicode-display_width (1.4.0) 117 | virtus (1.0.5) 118 | axiom-types (~> 0.1) 119 | coercible (~> 1.0) 120 | descendants_tracker (~> 0.0, >= 0.0.3) 121 | equalizer (~> 0.0, >= 0.0.9) 122 | 123 | PLATFORMS 124 | ruby 125 | 126 | DEPENDENCIES 127 | em-http-request 128 | goliath 129 | grape 130 | rack-contrib (~> 1.4.0) 131 | rack-test 132 | rake 133 | rspec 134 | rubocop 135 | 136 | RUBY VERSION 137 | ruby 2.5.3p105 138 | 139 | BUNDLED WITH 140 | 1.16.6 141 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: ruby app.rb -sv -p $PORT 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Grape API on Goliath 2 | ==================== 3 | 4 | [![Build Status](https://secure.travis-ci.org/ruby-grape/grape-on-goliath.png)](http://travis-ci.org/ruby-grape/grape-on-goliath) 5 | [![Dependency Status](https://gemnasium.com/ruby-grape/grape-on-goliath.svg)](https://gemnasium.com/ruby-grape/grape-on-goliath) 6 | 7 | A [Grape](http://github.com/ruby-grape/grape) API mounted on [Goliath](http://postrank-labs.github.io/goliath), a non-blocking Ruby web server framework. 8 | 9 | * [ping](api/ping.rb): a hello world example that returns a JSON document 10 | 11 | Heroku 12 | ------ 13 | 14 | Grape-on-goliath is deployed on Heroku at [grape-on-goliath.herokuapp.com](http://grape-on-goliath.herokuapp.com/api/ping). 15 | 16 | Run 17 | --- 18 | 19 | ``` 20 | $ bundle install 21 | $ bundle exec ruby app.rb -sv 22 | [92117:INFO] 2013-10-18 12:54:33 :: Starting server on 0.0.0.0:9000 in test mode. Watch out for stones. 23 | ``` 24 | 25 | ### Hello World 26 | 27 | Navigate to http://0.0.0.0:9000/api/ping with a browser or use `curl`. 28 | 29 | ``` 30 | $ curl http://0.0.0.0:9000/api/ping 31 | 32 | {"ping":"pong"} 33 | ``` 34 | 35 | List Routes 36 | ----------- 37 | 38 | ``` 39 | rake routes 40 | ``` 41 | 42 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler/setup' 3 | 4 | require 'rake' 5 | 6 | require 'rspec/core' 7 | require 'rspec/core/rake_task' 8 | 9 | RSpec::Core::RakeTask.new(:spec) do |spec| 10 | spec.pattern = FileList['spec/**/*_spec.rb'] 11 | end 12 | 13 | task :environment do 14 | ENV['RACK_ENV'] ||= 'development' 15 | require File.expand_path('config/environment', __dir__) 16 | end 17 | 18 | task routes: :environment do 19 | Acme::API.routes.each do |route| 20 | p route 21 | end 22 | end 23 | 24 | require 'rubocop/rake_task' 25 | RuboCop::RakeTask.new(:rubocop) 26 | 27 | task default: %i[rubocop spec] 28 | -------------------------------------------------------------------------------- /api/ping.rb: -------------------------------------------------------------------------------- 1 | module Acme 2 | class Ping < Grape::API 3 | format :json 4 | get '/ping' do 5 | { ping: 'pong' } 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('config/environment', __dir__) 2 | -------------------------------------------------------------------------------- /app/acme_app.rb: -------------------------------------------------------------------------------- 1 | module Acme 2 | class App < Goliath::API 3 | use Goliath::Rack::Params 4 | use Goliath::Rack::Render 5 | 6 | def response(env) 7 | Acme::API.call(env) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/api.rb: -------------------------------------------------------------------------------- 1 | module Acme 2 | class API < Grape::API 3 | prefix 'api' 4 | format :json 5 | mount ::Acme::Ping 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'api')) 2 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'app')) 3 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 4 | 5 | require 'boot' 6 | 7 | Bundler.require :default, ENV['RACK_ENV'] 8 | 9 | Dir[File.expand_path('../api/*.rb', __dir__)].each do |f| 10 | require f 11 | end 12 | 13 | require 'goliath' 14 | require 'api' 15 | require 'acme_app' 16 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler/setup' 3 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | ENV['RACK_ENV'] ||= 'test' 2 | 3 | require File.expand_path('application', __dir__) 4 | -------------------------------------------------------------------------------- /spec/api/ping_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Acme::API do 4 | include Goliath::TestHelper 5 | 6 | it 'ping' do 7 | with_api Acme::App do 8 | get_request(path: '/api/ping') do |async| 9 | expect(async.response).to eq({ ping: 'pong' }.to_json) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | ENV['RACK_ENV'] ||= 'test' 4 | 5 | require 'rack/test' 6 | 7 | require File.expand_path('../config/environment', __dir__) 8 | 9 | RSpec.configure do |config| 10 | config.mock_with :rspec 11 | config.expect_with :rspec 12 | config.raise_errors_for_deprecations! 13 | end 14 | 15 | require 'goliath/test_helper' 16 | --------------------------------------------------------------------------------