Ruby
Rails
RESTful
swagger

RailsのAPIをswaggerでドキュメント化してみる

More than 1 year has passed since last update.

最近Railsを使用してAPIを作成することが多いのですが、静的にドキュメントにリクエストパラメータが〇〇で、レスポンスが□□で...の用に書くのがたるくなってきたので、何か良いツールが無いかと探していた所、Swaggerというツールを見つけました。


Swaggerについて

公式サイト

APIのパス、説明、リクエストパラメータ、レスポンス等を記述したJSONファイルを、Swaggerを使用することで、Web上で、インタラクティブにRestfulAPIの動作確認も行えるOSSです。

swagger.png

現行バージョンは2.0で、こちらについては、Web上でymlを記載するだけで生成してくれるエディターが存在します。

http://editor.swagger.io#/


Railsで作成したAPIに対してSwaggerを使用する

RailsでSwaggerのJSONを生成する場合、いくつかの方法があります。



  • grape-swaggerというgemでgrapeの記法で使用する


  • swagger-docsというgemでRailsのコントローラ、ルーティングを動的にJSONにパースする(しかし1.2しか対応していない)


  • ruby-swaggerというgemで頑張る(多分これを使うくらいなら上記のエディタの方が楽)

それで、今回は既存のRailsのRestfulAPIに対してドキュメントを記載したかったため、swagger-docsを採用しました。


swagger-docs


インストール

Gemfileに以下を追記します


Gemfile

# grapeは使用しないが、中にswagger-uiのassets一式が入っているので、viewに利用

gem 'grape-swagger-rails', '~> 0.3.0'
gem 'swagger-docs', '~> 0.2.9'


設定

initializers以下に追加して、初期化時に読み込ませます


swagger_docs.rb

# Swagger settings

# baseのcontrollerの指定、変換パスの設定
class Swagger::Docs::Config
def self.base_api_controller; ActionController::API end
def self.transform_path(path, api_version); "apidocs/#{path}" end
end

# 出力JSON設定
Swagger::Docs::Config.register_apis({
"v1" => {
:api_extension_type => nil,
:api_file_path => "public/apidocs/", # JSONが置かれるPATH
:base_path => "http://localhost:3000/", # 最後の`/`が置換されてしまうのでURLを記載
:clean_directory => true,
:formatting => :pretty,
:camelize_model_properties => false,
:controller_base_path => "",
:attributes => {
:info => {
"title" => "Books API",
"description" => "Books operation API",
"contact" => "tora.1986.tatsu@gmail.com",
"license" => "Apache 2.0",
"licenseUrl" => "http://www.apache.org/licenses/LICENSE-2.0.html"
}
}
}
})

GrapeSwaggerRails.options.app_name = "Books API"
# 基盤となるJSON
GrapeSwaggerRails.options.url = "/apidocs/api-docs.json"
# こっちの`/`は置換されないのでこれでOK
GrapeSwaggerRails.options.app_url = "/"



Routing

config/routes.rbに以下を追加


routes.rb

  mount GrapeSwaggerRails::Engine => "/swagger"



assets

JS,CSSの読み込みを追記


  • app/assets/javascripts/application.js


application.js

//

//= require_tree .


  • app/assets/stylesheets/application.css


application.css

/*

*= require_tree .
*/



controllersにswagger-docsの記述を追加


controllerの指定

swagger_controller :controller名, "説明"

controller名を指定します。指定したcontroller名から動的にルーティング情報を読み込んでくれます。

  swagger_controller :Books, "Book"


apiの指定

Routingのpathを指定することで、JSONに出力するpathを指定できます。

swagger_api :path名 do ~ end

  swagger_api :show do

summary "Get a book"
consumes [ "application/json" ]
param :path, :id, :integer, :required, "Book Id"
response :ok, "Success", :Book
response :not_found
response :internal_server_error
end


  • summary : APIのサマリー

  • consumes : Content-Type

  • param : パラメータ指定


    • header : ヘッダー

    • path : URL path

    • form : FORMパラメータ

    • body : JSON Body



  • response : レスポンス(Rackの識別名が使用できる)


モデルオブジェクトの指定

Railsのモデルとは別で、swagger自体にモデルオブジェクトの記述方法が存在しており、これは、レスポンスのExampleや、パラメータにJSONを指定したいときに呼び出して使うことが出来ます。

swagger_model :モデル名 do ~ end

  swagger_api :create do

summary "Create a book image"
consumes [ "application/json" ]
param :body, :body, :object, :required, "Book image parameters", { "$ref": "BookImage" }
response :ok, "Success", :BookImage
response :not_found
response :internal_server_error
end

swagger_model :BookImage do
description "Book a object"
property :id, :integer, :required, "Book image Id"
property :book_id, :integer, :required, "Book Id"
property :url, :string, :required, "Book image URL"
property :alt, :string, :required, "Book image alt"
end


  • description : モデルの説明

  • property : モデルのプロパティ

記載したモデルをswagger_apiブロック内のresponseの第3引数に渡すことで、アウトプットJSONのサンプルに指定できたり、paramの第6引数はハッシュ形式で渡すことが可能なので、{ "$ret": "Model" } と指定することで、パラメータをJSON形式で渡すことが出来るようになります。

その他の詳細な書き方については、出力されたJSONを公式のドキュメントと見比べて行くといいと思います。

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/1.2.md


JSONの生成

swagger-docsの形式で記述ができたら、swagger形式のJSONを生成するために下記のRakeタスクを実行します。

$ rake swagger:docs

public以下にswaggerの設定で指定したディレクトリが作成されていれば成功です。

起動して確認してみましょう。

$ rails s

http://localhost:3000/swagger/

今回作成したサンプルです。

https://github.com/kitaro-tn/swagger-sample-books