APIモードによるWebサービス作成の方法
RailsのAPIモードの有意性を十分に感じたところで、Webサービスの構築事例に入っていきましょう。投稿者とメッセージ、投稿日時からなる簡単なメッセージボードサービスを作成しながら、APIモードの使い方を紹介していきます。
アプリケーションをAPIモードで作成する
APIモードの利用は簡単です。通常のRailsアプリケーションと同じく、rails newコマンドを使います。大きく異なる点としては、--apiオプションを指定するだけです。これにより、ビューを持たないAPI提供に特化したアプリケーションが作成されます。既定では、Action MailerやAction Cableなどのコンポーネントも組み込まれるので、不要ならば--skip-xxxxオプションで外しましょう。
% rails new message_api --api …略…
コマンドの出力は省略していますが、表示されるメッセージを注意して見ると、作成したアセットやヘルパーを、すぐに削除してしまっています。Webサービスではビューが不要なので、アセットやヘルパーも不要になるからです。
作成されるフォルダとファイルには、主に以下のような相違があります。
- ビューに相当するファイルが存在しない(Viewフォルダはあるが、Action Mailerのメールテンプレートなどのみが置かれる)
- コントローラのための基底クラスApplicationControllerがActionController::APIを継承する(通常はActionController::Base)
- config.api_onlyパラメータがtrueに設定される
- クッキーなどAPI提供では不要な機能は省かれる
config/application.rbファイルでは、APIモードであることを示すconfig.api_onlyパラメータがtrueに設定されます。既存のアプリケーションをAPI化する場合も、このパラメータを追加する必要があります。
config.api_only = true
この他は、ほぼ通常のアプリケーションにおけるものと同じと思ってよいでしょう。ジェネレータ機能により、モデルやコントローラを個別に作成したり、ScaffoldingによりCRUD機能を一度に実装したりといったことが可能です。また、リソースベースのルーティング機能も利用できます。
メッセージボードAPIを作成する
作成したアプリケーションに、APIを実装していきましょう。APIが扱うデータであるモデルMessageは、表1の通りとします。
フィールド | 型 | 概要 |
---|---|---|
name | text | 投稿者 |
message | text | メッセージの内容 |
posted | datetime | 投稿日時 |
これを踏まえて、Scaffoldingを実行します。APIモードで変わるところはありません。
% rails generate scaffold message name:text content:text posted:datetime
重ねてになりますが、ビューのファイルは一切生成されません。また、コントローラにおけるレンダリング形式が既定でJSONとなっています。例えば以下は、Createアクションメソッドの内容です。
def create @message = Message.new(message_params) if @message.save render json: @message, status: :created, location: @message else render json: @message.errors, status: :unprocessable_entity end end
APIモードでも、ルーティングはリソースベースの規約に準じます。リソースベースのルーティングルールがconfig/routes.rbファイルに記述されますので、代表的なアクションに対して以下のようなルートが利用可能になっています。これらのルートを用いれば、自動生成されたAPIが即座に利用できます。
- index…一覧(GET、/messages)
- show…詳細(GET、/messages/:id)
- create…作成(POST、/messages)
- update…更新(PATCH/PUT、/messages/:id)
- delete…削除(DELETE、/messages/:id)
[NOTE]XML形式も使える
近年ではあまり使われませんがXML形式で返すことも可能です。この場合は、renderメソッドの「json:」を「xml:」に変更します。それに加えて、Gemライブラリactivemodel-serializer-xmlのインストールが必要になります。
続けてデータベースのマイグレーションを実行します。
% rails db:migrate
この時点ではデータが何もないので、seedsデータをdb/seeds.rbファイルに例えば以下のような内容で記述します。
Message.create(name: "Nao", content: "こんにちは!", posted: "2022/12/19 18:01:34") Message.create(name: "Takashi", content: "また来ました。", posted: "2022/12/19 19:22:23") Message.create(name: "Yuuta", content: "大学行ってくる", posted: "2022/12/19 10:10:54")
シードファイルは、rails db:seedコマンドで実行できます。
% rails db:seed
APIの動作をWebブラウザで確かめてみる
ここまでの作業に問題なければ、Pumaサーバを起動してWebブラウザからAPIを呼び出してみましょう。JSONを返すので、参照系だけならWebブラウザでテストできます。「http://localhost:3000/messages」にアクセスして、先ほど登録したデータの一覧(index)がJSON形式で表示されれば成功です(図2)。
% rails server
[NOTE]WebブラウザでJSONを見やすく表示するJSON Viewer
Google Chromeの既定では、JSONのデータが改行もインデントもなくズラッと表示されます。そのままではデータの構造を確認する場合に不便なので、拡張機能「JSON Viewer」を入れておくことをおすすめします。下記URLから「Chromeウェブストア」をChromeで開き、検索ボックスに「JSON Viewer」と入れて表示される候補から「json viewer」をクリックします。その後表示される画面で手順に従いJSON Viewerをインストールします。図2の画面は、JSON Viewerがインストールされているときのものです。
APIの動作を汎用クライアントで確かめてみる
上記ではWebブラウザでAPIをテストしてみましたが、基本的にできることは参照系のみとなります。そこで、汎用的なツールを使って更新系のAPIもテストしてみましょう。ここで使用するのは、Linux/UNIX系では一般的なcurl(カール、Client URL)コマンドです。このコマンドは、任意の宛先(URL)にHTTP/HTTPSによるリクエストを発行し、レスポンスの内容を表示するというシンプルな機能を持ったツールです。このcurlコマンドを使って、一覧を取得してみましょう(index)。
% curl http://localhost:3000/messages/ [{"id":1,"name":"Nao","content":"こんにちは!","posted":"2022-12-19T18:01:34.000Z","created_at":"2022-12-19T09:07:34.682Z","updated_at":"2022-12-19T09:07:34.682Z"},{"id":2,"name":"Takashi","content":"また来ました。","posted":"2022-12-19T19:22:23.000Z","created_at":"2022-12-19T09:07:34.702Z","updated_at":"2022-12-19T09:07:34.702Z"},{"id":3,"name":"Yuuta","content":"大学行ってくる","posted":"2022-12-19T10:10:54.000Z","created_at":"2022-12-19T09:07:34.728Z","updated_at":"2022-12-19T09:07:34.728Z"}]
以下は、IDが1であるレコードのみを取得しています(show)。
% curl http://localhost:3000/messages/1 {"id":1,"name":"Nao","content":"こんにちは!","posted":"2022-12-19T18:01:34.000Z","created_at":"2022-12-19T09:07:34.682Z","updated_at":"2022-12-19T09:07:34.682Z"}
同様に、作成(create)と更新(update)、削除(delete)も自在です。作成では、curlコマンドの既定であるGETメソッドではなくPOSTメソッドを指定して、コンテンツデータとしてレコードの内容を送信します。
% curl http://localhost:3000/messages/ -H "Content-Type: application/json" -X POST -d '{"name": "Shino", "content": "晩ご飯どうする?", "posted": "2022/12/19 20:45:22"}' {"id":4,"name":"Shino","content":"晩ご飯どうする?","posted":"2022-12-19T20:45:22.000Z","created_at":"2022-12-19T11:48:30.000Z","updated_at":"2022-12-19T11:48:30.000Z"}
このとき、-Hオプションはリクエストヘッダの指定、-XオプションはHTTPメソッドの指定、-dオプションは送信データの指定です。さらに以下は、更新の例です。PATCHメソッドを指定しています。
% curl http://localhost:3000/messages/4 -H "Content-Type: application/json" -X PATCH -d '{"name": "Shino", "content": "またね!", "posted": "2022/12/19 20:55:43"}' {"name":"Shino","content":"またね!","posted":"2022-12-19T20:55:43.000Z","id":4,"created_at":"2022-12-19T11:48:30.000Z","updated_at":"2022-12-19T11:54:57.635Z"}
最後に、追加、更新したレコードを削除します。
% curl http://localhost:3000/messages/4 -X DELETE % curl http://localhost:3000/messages/ [{"id":1,"name":"Nao","content":"こんにちは!","posted":"2022-12-19T18:01:34.000Z","created_at":"2022-12-19T09:07:34.682Z","updated_at":"2022-12-19T09:07:34.682Z"},{"id":2,"name":"Takashi","content":"また来ました。","posted":"2022-12-19T19:22:23.000Z","created_at":"2022-12-19T09:07:34.702Z","updated_at":"2022-12-19T09:07:34.702Z"},{"id":3,"name":"Yuuta","content":"大学行ってくる","posted":"2022-12-19T10:10:54.000Z","created_at":"2022-12-19T09:07:34.728Z","updated_at":"2022-12-19T09:07:34.728Z"}] 追加したレコード4が存在しない
[NOTE]WindowsではPowerShellのInvoke-WebRequestコマンドを使える
Windowsでは、PowerShellのInvoke-WebRequestコマンドが同様の目的に使えます。curlコマンドはInvoke-WebRequestコマンドのエイリアスとなっており、コマンド名のみを入力して実行することで、対話的にリクエストを発行して結果を取得できます。