techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

既存 Rails アプリに REST API ドキュメンテーションを追加する

既存 Rails アプリに REST API ドキュメンテーションを追加する

Rails チュートリアルで作成したアプリに REST API を実装するシリーズ。

  • Doorkeeper による OAuth2 認可
  • Grape による REST API 実装

と進めてきて、今回は Swagger(OpneAPI) を用いたドキュメンテーションを追加してみる。

OpenAPI とは

Open API Initiative

  • インタラクティブなドキュメントの作成、閲覧
  • ドキュメントからのスタブサーバーの自動生成
  • ドキュメントからのクライアントコードの自動生成

ドキュメントを yml で記述していく方法と、実装済から生成する方法の2通りの作り方が可能。

今回は後者を試す。

準備

ありがたいことに Rails と連携できる便利 Gem を作っている方が 色々いらっしゃる ようで。
RSpec 前提のものが多い。(Rails チュートリアルは minitest で進んでたからこの辺はぐぬぬ

rswag とか強そうなんだけど。
domaindrivendev_rswag_ Seamlessly adds a Swagger to Rails-based API’s

今回選んだのはこれら。

この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

なんかページ数指定して続きを取る系が酷評されてるのを昔聞いた覚えが。