APIモードでアプリを作成
前回の内容
ti-tomo-knowledge.hatenablog.com
前回Railsをセットアップして起動させるところまで進めましたが、今回は主にAPI用でRailsを使いたいので、GET処理をするAPIを作ってみたいと思います。(POST処理は次回)
今回は再度APIモードでRailsのプロジェクトを作り直します。
なぜかというと、APIモードでプロジェクトを作成した場合、jbuilderというJSONを生成するためのライブラリが自動で使える状態になるからです。
また、APIでは不要となるview等の描画で使用するファイルをインストールすることも無くなります。
決してAPIしかできなくなるわけではないのでご注意ください。
ではさっそく、、、
前回の手順でいうところの
bundle init
から新たにやり直す形になります。
APIモードで作成する場合は前回以下のようにしていたところを、
bundle exec rails new .
以下のコマンドにしてプロジェクトを作成してください。
bundle exec rails new . --api
モデルの作成
まずはモデルを作成しましょう。
以下のコマンドで、titleとbodyというカラムを持つArticleというモデルを作成してください。
rails g model article title:string body:string
上手くいくと以下のようにファイルが作成されます。
Running via Spring preloader in process 42139 invoke active_record create db/migrate/20190712070305_create_articles.rb create app/models/article.rb invoke test_unit create test/models/article_test.rb create test/fixtures/articles.yml
ここで注目していただきたいのが、「db/migrate/20190712070305_create_articles.rb」というマイグレーションのファイルです。
中身を見てみると、以下のようにテーブル作成の定義が書かれています。
class CreateArticles < ActiveRecord::Migration[5.2] def change create_table :articles do |t| t.string :title t.string :body t.timestamps end end end
「rake db:migrate」でマイグレーションを実行できるのですが、先にDBの設定が必要になります。
私はMySQLを使いたいので、MySQLと接続できるライブラリをGemfileに追加します。
gem 'mysql2'
そしてライブラリの反映
bundle install
次に、config/database.ymlファイルを変更しましょう。
もちろん設定値(database、username、password等)はそれぞれの環境に合わせてください。
development: adapter: mysql2 encoding: utf8 database: rails_test username: root password: host: localhost
※また別の機会に触れますが、本番環境の接続情報は環境変数などで設定しましょうね。
あとはマイグレーションの実行です。
rake db:migrate
マイグレーションが完了です!
== 20190712070305 CreateArticles: migrating =================================== -- create_table(:articles) -> 0.0076s == 20190712070305 CreateArticles: migrated (0.0077s) ==========================
データベースにarticlesというテーブルができているはずです。
テスト用にデータを適当に挿入しておきます。
INSERT INTO articles(title, body, created_at, updated_at) VALUES ('AAAA', 'BBBB', '2019/04/01', '2019/05/01'),('CCCC', 'DDDD', '2019/04/02', '2019/05/02');
コントローラの作成
次にコントローラの作成です。
APIのコントローラ系はapiディレクトリの下に配置しておきたいので、以下のようなコマンドを発行します。
rails g controller api/articles
すると結果はこんな感じに。
create app/controllers/api/articles_controller.rb invoke test_unit create test/controllers/api/articles_controller_test.rb
ここで1つ蛇足ですが、今回APIモードでアプリを作っていますが、APIモードではなく、通常であればこんなに大量にファイルができます。
create app/controllers/api/articles_controller.rb invoke erb create app/views/api/articles invoke test_unit create test/controllers/api/articles_controller_test.rb invoke helper create app/helpers/api/articles_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/api/articles.coffee invoke scss create app/assets/stylesheets/api/articles.scss
viewやscssなど不要なファイルも盛りだくさんです。
よって、APIをメインで使うサービスであればぜひAPIモードで作成しましょう。
次にURLのルーティングです。
今回は「ドメイン/api/articles」で目的の値を表示させたいと思っているので、「config/routes.rb」ファイルに対して以下のようにしてください。
Rails.application.routes.draw do namespace 'api' do resources :articles end end
正しく設定できているか確認です。
rake routes
Prefix Verb URI Pattern Controller#Action api_articles GET /api/articles(.:format) api/articles#index POST /api/articles(.:format) api/articles#create api_article GET /api/articles/:id(.:format) api/articles#show PATCH /api/articles/:id(.:format) api/articles#update PUT /api/articles/:id(.:format) api/articles#update DELETE /api/articles/:id(.:format) api/articles#destroy
問題ありませんね。
次にコントローラの中身ですが、今回は簡易的にindexだけ作成し、先ほど投入したテストデータが表示されるようにします。
module Api class ArticlesController < ApplicationController def index articles = Article.order(created_at: :desc) render json: { status: 'OK', data: articles } end end end
apiディレクトリ直下にコントローラを配置しているので、「module Api」を先頭に入れる必要があります。
さあ、いよいよ起動させます。
rails s
初期状態では、ドメインはローカルホストになるので、コンソールから以下URLで確認しましょう。
curl -s http://localhost:3000/api/articles
問題なく値が取れてますね!
{"status":"OK","data":[{"id":2,"title":"CCCC","body":"DDDD","created_at":"2019-04-02T00:00:00.000Z","updated_at":"2019-05-02T00:00:00.000Z"},{"id":1,"title":"AAAA","body":"BBBB","created_at":"2019-04-01T00:00:00.000Z","updated_at":"2019-05-01T00:00:00.000Z"}]}
今回は簡易的な実装なのでコンソールから確認しましたが、実際は他のアプリから呼ばれるものになるはずです。
そうなるとクロスドメインの設定などまだまだやることは盛りだくさん。。。
とりあえず次回はPOST処理編です。