How to build Rails5 API + Redux ToDo Application その1
Rails5から実装されるAPI専用アプリケーションの作成手順です。
プロジェクトの生成からAPI経由でのアクセスまで試してみます。
Rails5の取得
githubからRails5を取得するため適当なディレクトリに以下のGemfileを作成します。
Gemfile
source 'https://rubygems.org' gem 'rails', github: 'rails/rails'
Gemfileを作成後、以下のコマンドを実行し直下にrailsを取得します。
$ bundle install --path vendor/bundle
Rails5 APIアプリケーションの作成
同ディレクトリで以下のコマンドを実行します。
rails newコマンドにapiオプションを指定するとAPIのみのアプリケーションが生成されます。
$ bundle exec rails new <application-name> --api
雛形の作成
生成されたアプリケーションのディレクトリに移動し、APIの雛形となるscaffoldを生成します。
$ bin/rails g scaffold todo title completed:boolean order:integer Running via Spring preloader in process 3582 invoke active_record create db/migrate/20160120044614_create_todos.rb create app/models/todo.rb invoke test_unit create test/models/todo_test.rb create test/fixtures/todos.yml invoke resource_route route resources :todos invoke scaffold_controller create app/controllers/todos_controller.rb invoke test_unit create test/controllers/todos_controller_test.rb
雛形を作成したらDBのmigrationをします。
$ bin/rails db:migrate == 20160120044614 CreateTodos: migrating ====================================== -- create_table(:todos) -> 0.0016s == 20160120044614 CreateTodos: migrated (0.0016s) =============================
サーバーの起動
以下のコマンドを実行しサーバーを起動します。
$ bin/rails s => Booting Puma => Rails 5.0.0.beta1 application starting in development on http://localhost:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server I, [2016-01-20T13:57:13.149636 #10181] INFO -- : Celluloid 0.17.3 is running in BACKPORTED mode. [ http://git.io/vJf3J ] Puma 2.15.3 starting... * Min threads: 0, max threads: 16 * Environment: development * Listening on tcp://localhost:3000
※2016/01/20 サーバー起動時にactionpackがエラーを吐き出します。取り急ぎ実行したい場合は以下のファイルを編集して下さい。
config/initializers/per_form_csrf_tokens.rb
# Be sure to restart your server when you modify this file. # Enable per-form CSRF tokens. # 下記の行をコメントアウト # Rails.application.config.action_controller.per_form_csrf_tokens = true
APIへのアクセス
ToDOの作成
クライアント
$ curl -H "Content-Type:application/json; charset=utf-8" -X POST -d '{ "title":"単2電池を買いに行く", "order":1, "completed":false }' http://localhost:3000/todos {"id":1,"title":"単2電池を買いに行く","completed":false,"order":1,"created_at":"2016-01-20T05:12:28.395Z","updated_at":"2016-01-20T05:12:28.395Z"}% curl -H "Content-Type:application/json; charset=utf-8" -X POST -d '{ "title":"お土産を買いに行く", "order":1, "completed":false }' http://localhost:3000/todos {"id":2,"title":"お土産を買いに行く","completed":false,"order":1,"created_at":"2016-01-20T05:13:50.865Z","updated_at":"2016-01-20T05:13:50.865Z"}%
サーバー
Started POST "/todos" for ::1 at 2016-01-20 14:04:17 +0900 ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations" Processing by TodosController#create as */* Parameters: {"title"=>"単2電池を買いに行く", "order"=>1, "completed"=>false, "todo"=>{"title"=>"単2電池を買いに行く", "completed"=>false, "order"=>1}} (0.1ms) begin transaction SQL (7.8ms) INSERT INTO "todos" ("title", "completed", "order", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["title", "単2電池を買いに行く"], ["completed", false], ["order", 1], ["created_at", 2016-01-20 05:04:17 UTC], ["updated_at", 2016-01-20 05:04:17 UTC]] (1.1ms) commit transaction Completed 201 Created in 32ms (Views: 1.5ms | ActiveRecord: 9.8ms) Started POST "/todos" for ::1 at 2016-01-20 14:13:50 +0900 Processing by TodosController#create as */* Parameters: {"title"=>"お土産を買いに行く", "order"=>1, "completed"=>false, "todo"=>{"title"=>"お土産を買いに行く", "completed"=>false, "order"=>1}} (0.1ms) begin transaction SQL (0.4ms) INSERT INTO "todos" ("title", "completed", "order", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["title", "お土産を買いに行く"], ["completed", false], ["order", 1], ["created_at", 2016-01-20 05:13:50 UTC], ["updated_at", 2016-01-20 05:13:50 UTC]] (0.7ms) commit transaction Completed 201 Created in 4ms (Views: 0.6ms | ActiveRecord: 1.2ms)
ToDO一覧の取得
クライアント
$ curl http://localhost:3000/todos [{"id":1,"title":"単2電池を買いに行く","completed":false,"order":1,"created_at":"2016-01-20T05:12:28.395Z","updated_at":"2016-01-20T05:12:28.395Z"},{"id":2,"title":"お土産を買いに行く","completed":false,"order":1,"created_at":"2016-01-20T05:13:50.865Z","updated_at":"2016-01-20T05:13:50.865Z"}]%
サーバー
Started GET "/todos" for ::1 at 2016-01-20 14:15:23 +0900 Processing by TodosController#index as */* Todo Load (0.2ms) SELECT "todos".* FROM "todos" Completed 200 OK in 3ms (Views: 2.1ms | ActiveRecord: 0.2ms)
ToDOの更新
クライアント
curl -H "Content-Type:application/json; charset=utf-8" -X PATCH -d '{ "completed":true }' http://localhost:3000/todos/1 {"id":1,"completed":true,"title":"単2電池を買いに行く","order":1,"created_at":"2016-01-20T05:12:28.395Z","updated_at":"2016-01-20T05:17:05.151Z"}%
サーバー
Started PATCH "/todos/1" for ::1 at 2016-01-20 14:17:05 +0900 Processing by TodosController#update as */* Parameters: {"completed"=>true, "id"=>"1", "todo"=>{"completed"=>true}} Todo Load (0.3ms) SELECT "todos".* FROM "todos" WHERE "todos"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] (0.1ms) begin transaction SQL (0.4ms) UPDATE "todos" SET "completed" = ?, "updated_at" = ? WHERE "todos"."id" = ? [["completed", true], ["updated_at", 2016-01-20 05:17:05 UTC], ["id", 1]] (1.0ms) commit transaction Completed 200 OK in 75ms (Views: 0.5ms | ActiveRecord: 1.8ms)