5分でRails5のAPI modeを試してみた
Rails5のbeta2が公開されて、1ヶ月近く経とうとしています。
Rails5の新機能の一つAPI modeをさくっとやってみて、どんな感じになるのか見てみたいと思い、やってみました。
API modeについて
json出力のみに特化した、コンパクトなFWを提供してくれる機能
Install
$ gem install rails -v 5.0.0.beta2 --pre $ gem list | grep rails rails (5.0.0.beta2) rails-deprecated_sanitizer (1.0.3) rails-dom-testing (1.0.7) rails-html-sanitizer (1.0.3) sprockets-rails (3.0.1)
railsアプリ作成
$ rails new backend --api create create README.md create Rakefile create config.ru create .gitignore create Gemfile create app create app/assets/config/manifest.js create app/assets/javascripts/application.js create app/assets/javascripts/cable.coffee create app/assets/stylesheets/application.css create app/channels/application_cable/channel.rb create app/channels/application_cable/connection.rb create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/jobs/application_job.rb create app/mailers/application_mailer.rb create app/models/application_record.rb create app/views/layouts/application.html.erb create app/views/layouts/mailer.html.erb create app/views/layouts/mailer.text.erb create app/assets/images/.keep create app/assets/javascripts/channels create app/assets/javascripts/channels/.keep create app/controllers/concerns/.keep create app/models/concerns/.keep create bin create bin/bundle create bin/rails create bin/rake create bin/setup create bin/update create config create config/routes.rb create config/application.rb create config/environment.rb create config/secrets.yml create config/cable.yml create config/puma.rb create config/environments create config/environments/development.rb create config/environments/production.rb create config/environments/test.rb create config/initializers create config/initializers/active_record_belongs_to_required_by_default.rb create config/initializers/application_controller_renderer.rb create config/initializers/assets.rb create config/initializers/backtrace_silencers.rb create config/initializers/callback_terminator.rb create config/initializers/cookies_serializer.rb create config/initializers/cors.rb create config/initializers/filter_parameter_logging.rb create config/initializers/inflections.rb create config/initializers/mime_types.rb create config/initializers/per_form_csrf_tokens.rb create config/initializers/request_forgery_protection.rb create config/initializers/session_store.rb create config/initializers/wrap_parameters.rb create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create lib create lib/tasks create lib/tasks/.keep create lib/assets create lib/assets/.keep create log create log/.keep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/robots.txt create test/fixtures create test/fixtures/.keep create test/fixtures/files create test/fixtures/files/.keep create test/controllers create test/controllers/.keep create test/mailers create test/mailers/.keep create test/models create test/models/.keep create test/helpers create test/helpers/.keep create test/integration create test/integration/.keep create test/test_helper.rb create tmp create tmp/.keep create tmp/cache create tmp/cache/assets create vendor/assets/stylesheets create vendor/assets/stylesheets/.keep remove app/assets remove lib/assets remove tmp/cache/assets remove vendor/assets remove app/helpers remove test/helpers remove app/views remove app/assets/javascripts remove config/initializers/assets.rb remove config/initializers/session_store.rb remove config/initializers/cookies_serializer.rb remove config/initializers/request_forgery_protection.rb remove config/initializers/per_form_csrf_tokens.rb run bundle install Fetching gem metadata from https://rubygems.org/........... Fetching version metadata from https://rubygems.org/... Fetching dependency metadata from https://rubygems.org/.. Resolving dependencies... Installing rake 10.5.0 Using concurrent-ruby 1.0.0 Using i18n 0.7.0 Using json 1.8.3 Using method_source 0.8.2 Installing minitest 5.8.4 Using thread_safe 0.3.5 Using builder 3.2.2 Using erubis 2.7.0 Using mini_portile2 2.0.0 Using nio4r 1.2.1 Using websocket-extensions 0.1.2 Using mime-types 2.99.1 Using arel 7.0.0 Using bundler 1.11.2 Installing byebug 8.2.2 with native extensions Installing puma 2.16.0 with native extensions Using thor 0.19.1 Installing redis 3.2.2 Installing spring 1.6.3 Installing sqlite3 1.3.11 with native extensions Using rack 2.0.0.alpha Using tzinfo 1.2.2 Using nokogiri 1.6.7.2 Using websocket-driver 0.6.3 Using mail 2.6.3 Using rack-test 0.6.3 Using sprockets 3.5.2 Using activesupport 5.0.0.beta2 Using loofah 2.0.3 Using rails-deprecated_sanitizer 1.0.3 Using globalid 0.3.6 Using activemodel 5.0.0.beta2 Using rails-html-sanitizer 1.0.3 Using rails-dom-testing 1.0.7 Using activejob 5.0.0.beta2 Using activerecord 5.0.0.beta2 Using actionview 5.0.0.beta2 Using actionpack 5.0.0.beta2 Using actioncable 5.0.0.beta2 Using actionmailer 5.0.0.beta2 Using railties 5.0.0.beta2 Using sprockets-rails 3.0.1 Using rails 5.0.0.beta2 Bundle complete! 7 Gemfile dependencies, 44 gems now installed. Use `bundle show [gemname]` to see where a bundled gem is installed. run bundle exec spring binstub --all * bin/rake: spring inserted * bin/rails: spring inserted
とりあえずのscaffold
$ bundle exec rails g scaffold Item name:string price:integer description:text Running via Spring preloader in process 53777 invoke active_record create db/migrate/20160223144234_create_items.rb create app/models/item.rb invoke test_unit create test/models/item_test.rb create test/fixtures/items.yml invoke resource_route route resources :items invoke scaffold_controller create app/controllers/items_controller.rb invoke test_unit create test/controllers/items_controller_test.rb
migrate
$ bundle exec rails db:migrate == 20160223144234 CreateItems: migrating ====================================== -- create_table(:items) -> 0.0010s == 20160223144234 CreateItems: migrated (0.0011s) =============================
routing確認
$ bundle exec rake routes Prefix Verb URI Pattern Controller#Action items GET /items(.:format) items#index POST /items(.:format) items#create item GET /items/:id(.:format) items#show PATCH /items/:id(.:format) items#update PUT /items/:id(.:format) items#update DELETE /items/:id(.:format) items#destroy
json固定のはずなのだが、(.:format)はまだ名残があるのか...
server起動
$ bundle exec rails s => Booting Puma => Rails 5.0.0.beta2 application starting in development on http://localhost:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server Puma 2.16.0 starting... * Min threads: 0, max threads: 16 * Environment: development * Listening on tcp://localhost:3000
curlで叩いてみる
create
$ curl -i "http://localhost:3000/items" -X POST -d "item[name]=item1" -d "item[price]=100" -d "item[description]=hogehogehoge" HTTP/1.1 201 Created X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Location: http://localhost:3000/items/2 Content-Type: application/json; charset=utf-8 ETag: W/"6535c375d722504d841583154c4cd772" Cache-Control: max-age=0, private, must-revalidate X-Request-Id: 9af3f18d-3def-492c-8726-81360555c34b X-Runtime: 0.006851 Transfer-Encoding: chunked {"id":2,"name":"item1","price":100,"description":"hogehogehoge","created_at":"2016-02-23T14:53:13.653Z","updated_at":"2016-02-23T14:53:13.653Z"}%
update
$ curl -i "http://localhost:3000/items/1" -X PUT -d "item[name]=item1" -d "item[price]=100" -d "item[description]=testtesttesttest" HTTP/1.1 200 OK X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Type: application/json; charset=utf-8 ETag: W/"07496e9d5347840a6f8afe9beff31e3c" Cache-Control: max-age=0, private, must-revalidate X-Request-Id: 7bd1f736-9654-494a-9f30-7e779dfcf00b X-Runtime: 0.010888 Transfer-Encoding: chunked {"id":1,"name":"item1","price":100,"description":"testtesttesttest","created_at":"2016-02-23T14:52:44.706Z","updated_at":"2016-02-23T15:27:55.731Z"}%
get
list
$ curl -i "http://localhost:3000/items" HTTP/1.1 200 OK X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Type: application/json; charset=utf-8 ETag: W/"4611f00ddf692b8aefeaf254441373c4" Cache-Control: max-age=0, private, must-revalidate X-Request-Id: fa956bfb-6856-41c0-a8df-d977342eb583 X-Runtime: 0.004649 Transfer-Encoding: chunked [{"id":1,"name":"item1","price":100,"description":"testtesttesttest","created_at":"2016-02-23T14:52:44.706Z","updated_at":"2016-02-23T15:27:55.731Z"},{"id":2,"name":"item1","price":100,"description":"hogehogehoge","created_at":"2016-02-23T14:53:13.653Z","updated_at":"2016-02-23T14:53:13.653Z"}]%
show
$ curl -i "http://localhost:3000/items/1" HTTP/1.1 200 OK X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Content-Type: application/json; charset=utf-8 ETag: W/"07496e9d5347840a6f8afe9beff31e3c" Cache-Control: max-age=0, private, must-revalidate X-Request-Id: 7cb6ae00-5e4a-4762-81ef-d7ef468fba2e X-Runtime: 0.003824 Transfer-Encoding: chunked {"id":1,"name":"item1","price":100,"description":"testtesttesttest","created_at":"2016-02-23T14:52:44.706Z","updated_at":"2016-02-23T15:27:55.731Z"}%
delete
$ curl -i "http://localhost:3000/items/1" -X DELETE HTTP/1.1 204 No Content X-Frame-Options: SAMEORIGIN X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff Cache-Control: no-cache X-Request-Id: fb8d04b3-b6d8-46ba-8836-5905a547fe6d X-Runtime: 0.005990
生成されたcontroller
app/controllers/items_controller.rb
class ItemsController < ApplicationController before_action :set_item, only: [:show, :update, :destroy] # GET /items def index @items = Item.all render json: @items end # GET /items/1 def show render json: @item end # POST /items def create @item = Item.new(item_params) if @item.save render json: @item, status: :created, location: @item else render json: @item.errors, status: :unprocessable_entity end end # PATCH/PUT /items/1 def update if @item.update(item_params) render json: @item else render json: @item.errors, status: :unprocessable_entity end end # DELETE /items/1 def destroy @item.destroy end private # Use callbacks to share common setup or constraints between actions. def set_item @item = Item.find(params[:id]) end # Only allow a trusted parameter "white list" through. def item_params params.require(:item).permit(:name, :price, :description) end end