APIãã¬ã¼ã ã¯ã¼ã¯GrapeãRuby on Railsã®ä¸ã§åããã¨é ãã
ããä»äºã§ã¹ããã©ç¨ã®APIãµã¼ãã¼ãä½ãäºã«ãªããREST-like APIãç°¡åã«ä½ãããã¬ã¼ã ã¯ã¼ã¯ grape ã調æ»ãã¦ã¿ã¾ãããgrapeã®è¯ãã¯ãDSLã§ç°¡åã«APIãµã¼ãã¼ãæ¸ããç¹ã¨Rackã§åã軽ããã¬ã¼ã ã¯ã¼ã¯ãªã®ã§Ruby on Railsã«æ¯ã¹é«ãããã©ã¼ãã³ã¹ãæå¾ ã§ããç¹ã§ãã
ã·ã¹ãã æ§æ
Grape㯠Mounting ã«æ¸ããã¦ããããã«ããã¤ãã®æ§æã§åããã¾ã
- Rack: Rackä¸ã§åãã
- ActiveRecord without Rails: Rackã®ä¸ã§åãããã© ActiveRecord ã使ã
- Rails: Ruby on Railsã®ä¸ã§åãã
- ...
ä»åã®ã·ã¹ãã ã§ã¯ç®¡çè ç¨ã®Webã¢ããªã¯ Ruby on Railsã§ä½ãã®ã§ãã¢ãã«ãå ±æã§ããRuby on Railsã«çµã¿è¾¼ã¿ä½¿ãã®ãé åçã§ãã
è©ä¾¡ç¨ã³ã¼ããä½ã£ã¦ã¿ã
æºå
- ã¾ãã¯Railsã®ããã¸ã§ã¯ããä½ããscaffoldã§ãã¤ãã®ã¢ããªãä½æ
$ rails new api_test
$ cd apt_test
$ rails g scaffold todo due:date task:string
- ãã¹ããã¼ã¿ä½æ db/seed.rb ãä½æ
Todo.delete_all 100.times { |i| Todo.create!(due: Time.now + i.day, task: sprintf("task%02d", i)) }
json.array!(@todos) do |todo| json.extract! todo, :id, :due, :task, :created_at, :updated_at end
Grape
grape ãã¼ã¸ã®æ å ±ãåºã« API ãä½æ
- Gemfile
source 'https://rubygems.org' .... gem 'grape'
- API ã®ã³ã¼ã
class SimpleApi < Grape::API version 'v1' format :json resource :todos do desc "Return all todos." get do Todo.all end end end
- config/routes.rb ã« APIããã¦ã³ã
Rails.application.routes.draw do resources :todos mount SimpleApi => '/api' end
- config/application.rb ã«APIã®ã³ã¼ããèªã¿è¾¼ãããã«è¨å®
module ApiTest class Application < Rails::Application .... config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] end end
ãã㧠http://localhost:3000/api/v1/todos ãã¢ã¯ã»ã¹ããã¨todosãã¼ãã«ã®å ¨å 容ãJSONã§åå¾ã§ãã¾ã
æ§è½ãæ°ã«ãªã
Ruby on Railsã®ã³ã¼ãã http://localhost:3000/todos.json 㧠JSONãè¿ããã¾ããgrapeãã©ããããæ§è½ãè¯ãã®ããæ¯è¼ãã¦ã¿ã¾ããã
æ¯è¼ããç°å¢ã¯å®éã®ç°å¢ã«è¿ããªãããã«
- RAILS_ENV 㯠production
- ãµã¼ãã¼ã¯ unicornãworker_processes 㯠4
- ã¢ããªã¯ EC2 t2.micro ã§å®è¡
- ãã ããRDBã¯sqlite3ã®ã¾ã¾ãNginxçã®ããã³ãã¨ã³ãã¯ç¡ã
ab -c 8 -n 1000 URL ã§æ§è½ãè¨æ¸¬
Framework | Requests per second |
---|---|
Grape within Rails | 33.66 |
Ruby on Rails | 34.49 |
Grape ã®æ§è½ã¯ Ruby on Rails ã¨åããããï¼ï¼ ãã¡ããããã¹ããã¼ã¿ãabã®ãã©ã¡ã¼ã¿ã«ããå¤å°ç¶æ³ã¯å¤ããã¾ããã»ã»ã»
ActiveRecord without Railsã試ãã
Rackã®ä¸ã§ç´æ¥åãã·ã³ãã«ãª grape ã®æ§è½ããããªã«ä½ãã®ã¯ç´å¾åºæ¥ãªãã£ãã®ã§ãActiveRecord without Rails ã§è©¦ãã¦ã¿ã¾ãã
- Rackã®ä¸ã§åãã grape.ru ãä½æ
require 'grape' require 'active_record' require 'sqlite3' require_relative 'app/api/simple_api' require_relative 'app/models/todo' use ActiveRecord::ConnectionAdapters::ConnectionManagement ActiveRecord::Base.configurations = YAML.load_file('config/database.yml') ActiveRecord::Base.establish_connection(:production) run SimpleApi
ãã® grape.ru ãæå®ã unicorn èµ·å
Framework | Requests per second |
---|---|
Grape | 56.65 |
Ruby on Rails ã«æ¯ã¹ 1.6åã®æ§è½ãåºã¾ããï¼
çµè«
ãã¹ãä¸ã®ãµã¼ãã¼ã®ã¡ã¢ãªã¼ä½¿ç¨éã調ã¹ã¦ã¿ã¾ãããå®ã¡ã¢ãªä½¿ç¨é(RES)㯠Ruby on Railsã«æ¯ã¹ãã¨åå以ä¸ã§ãã
Framework | Requests per second | VIRT(memory) | RES(memory) |
---|---|---|---|
Grape within Rails | 33.66 | 345308 | 91828 |
Ruby on Rails | 34.49 | 345308 | 91828 |
Grape | 56.65 | 253472 | 38852 |
çµè«ã¨ãã¦ã¯ãgrape ã使ã£ã¦ API ãµã¼ãã¼ãä½ããªã Rackãã¼ã¹ã§èµ·åãã Ruby on Railsã¨ã¯å¥ã«åãããæ¹ãè¯ãã
ãã ããéçºæ㯠Ruby on Railsã®ä¸ã§åãããæ¹ãéçºããããããç¥ãã¾ãããã