既存 Rails アプリに REST API ドキュメンテーションを追加する
既存 Rails アプリに REST API ドキュメンテーションを追加する
Rails チュートリアルで作成したアプリに REST API を実装するシリーズ。
- Doorkeeper による OAuth2 認可
- Grape による REST API 実装
と進めてきて、今回は Swagger(OpneAPI) を用いたドキュメンテーションを追加してみる。
OpenAPI とは
- インタラクティブなドキュメントの作成、閲覧
- ドキュメントからのスタブサーバーの自動生成
- ドキュメントからのクライアントコードの自動生成
ドキュメントを yml で記述していく方法と、実装済から生成する方法の2通りの作り方が可能。
今回は後者を試す。
準備
ありがたいことに Rails と連携できる便利 Gem を作っている方が 色々いらっしゃる ようで。
RSpec 前提のものが多い。(Rails チュートリアルは minitest で進んでたからこの辺はぐぬぬ
rswag とか強そうなんだけど。
domaindrivendev_rswag_ Seamlessly adds a Swagger to Rails-based API’s
今回選んだのはこれら。
- grape-swagger
- Grape で作成した REST API から、swagger 形式の JSON を生成してくれる
- GrapeSwaggerRails
- Rails アプリ上で Swagger UI が動かせる
この2つで最低限動かせるはず。
grape-swagger-entity を組み合わせてより何たらかんたらできそう。
grape-swagger
Gemfile に以下を追記する。
gem 'grape-swagger'
以下を実行。
$ bundle install
Usage に従う。
Mount all your different APIs (with Grape::API superclass) on a root node. In the root class definition, include add_swagger_documentation, this sets up the system and registers the documentation on ‘/swagger_doc’.
Oh…
前回 試行錯誤の上見出した実装方法は上記にそぐわないのでやり直し。
再度試行錯誤の結果以下のように落ち着いた。
$ tree app/api/ app/api/ ├── api.rb ├── v1 │ ├── root.rb │ └── users.rb └── v2 ├── root.rb └── users.rb
Grape と Rails の組み合わせではディレクトリ名とモジュール名を揃える、というのを念頭に。
ルーティングから設定し直し。
config/routes.rb
Rails.application.routes.draw do ・ ・ ・ mount API::Root => '/' end
app/api/api.rb
module API class Root < Grape::API format :json mount V1::Root mount V2::Root end end
app/api/v1/root.rb
require 'grape-swagger' module V1 class Root < Grape::API format :json mount V1::Users add_swagger_documentation end end
$ rails s
して https://[YOUR_APP_URL]/api/v1/swagger_doc
にアクセスすると、Swagger 用の JSON が返却される。
{ "info": { "title": "API title", "version": "0.0.1" }, "swagger": "2.0", "produces": [ "application/json" ], "host": "fierce-wave-40771.herokuapp.com", "tags": [ { "name": "users", "description": "Operations about users" } ], "paths": { "/api/v1/users": { "get": { "summary": "Return all users.", "description": "Return all users.", "produces": [ "application/json" ], "responses": { "200": { "description": "Return all users." } }, "tags": [ "users" ], "operationId": "getApiV1Users" } }, "/api/v1/users/{id}": { "get": { "summary": "Return a user.", "description": "Return a user.", "produces": [ "application/json" ], "parameters": [ { "in": "path", "name": "id", "description": "User id.", "type": "integer", "format": "int32", "required": true } ], "responses": { "200": { "description": "Return a user." } }, "tags": [ "users" ], "operationId": "getApiV1UsersId" } } } }
パスを v2 に変更すればもちろん v2 も返却される。
GrapeSwaggerRails
Swagger 用の JSON が生成できるようになったので、 これを Swagger UI で見れるようにする。
Gemfile に以下を追記する。
gem 'grape-swagger-rails'
以下を実行。
$ bundle install
以降、Usage に従う。
config/routes.rb
を修正してルーティングを追加する。
Rails.application.routes.draw do ・ ・ ・ mount API::Root => '/' mount GrapeSwaggerRails::Engine => '/swagger' end
config/initializers/swagger.rb
を作成し、以下を記載する。
GrapeSwaggerRails.options.url = '/api/v1/swagger_doc' GrapeSwaggerRails.options.app_url = 'https://[YOUR_APP_URL]'
上記は先ほど grape-swagger で作成した JSON ファイルを指すようにする。
$ rails s
して https://[YOUR_APP_URL]/swagger
にアクセスすると、Swagger UI が表示される。
これだと開発環境と本番環境で共用できないので動的に URL を変更する。
上記の2行目を以下で置き換える。
GrapeSwaggerRails.options.before_action do |request| GrapeSwaggerRails.options.app_url = request.protocol + request.host_with_port end
同じく $ rails s
して https://[YOUR_APP_URL]/swagger
にアクセスすると、Swagger UI が表示される。
その他
引き続き、
- OAuth2 認可情報のドキュメンテーションへの反映
- grape-swagger-entity を使ってレスポンスを整形
と進めていく。
そうこうしているうちに OpenAPI Specification の v3 が公開されてしまった。 The OAI Announces the OpenAPI Specification 3.0.0 – Open API Initiative
変更点について調べてみよっと。
REST API のページネーションについてはこの辺参考にすれば良いのだろうか。
Pagination in the REST API - Atlassian Developers
なんかページ数指定して続きを取る系が酷評されてるのを昔聞いた覚えが。