最近、バックエンドはRails(APIモード)、フロントはNuxt.jsといったフロントエンドとバックエンドが別々で、APIでやり取りさせるような構成が多くなってきました。
そういう場合にバックエンドとフロントエンドのIF(スキーマ)を管理するのにOpenAPI
というのがデファクトスタンダードになりつつあるようです。
自分自身、普通のモノリシックなRailsアプリケーションしか触ったことがなかったので、この辺キャッチアップできてなかったのですが、いろいろ環境とか作ったりしてなんとなく分かってきたので、メモしておきます📝
OpenAPIとは
OpenAPIとはもともとSwaggerと呼ばれるツールによって定義されたRESTfulなAPIの定義方法が標準化されてもののようです。
The OpenAPI Specification, formerly known as the Swagger Specification, is the world’s standard for defining RESTful interfaces. https://swagger.io/solutions/getting-started-with-oas/
いろいろ調べたところ下記のような周辺ツールも含めてOpenAPIと呼ばれているようです👀
tool | memo | link |
---|---|---|
Swagger Editor | OpenAPIを使ったAPI定義を良い感じにプレビューしながら書けるエディター | https://editor.swagger.io/ |
Swagger UI | OpenAPIを使ったAPI定義(yaml or json)からWebで閲覧可能な良い感じのAPI定義書を生成する | https://swagger.io/tools/swagger-ui/ |
OpenAPI Generator | OpenAPIを使ったAPI定義(yaml or json)からStabを作成するツール | https://openapi-generator.tech/ |
※OpenAPI Generator
はSwagger Codegenでも代用可能だが、現状はOpenAPI Generator
が主流らしい。
どうやらSwagger Codegenのv2とv3で大きな変更が入りPythonと同様なことが起こるんじゃないかといった懸念等がありForkされOpenAPI Generatorが作られたようです。
Swagger Codegen Fork: Q&A · OpenAPI Generator
以前説明したNuxt.jsとRailsのdocker環境にSwagger UIとOpenAPI Generatorを追加したので試したい方はこちらから
※Swagger Editorは自分の好きなEditorで書いたほうが使いやすい + 使いたい場合はWebでも使えるので含めない方針としました。
OpenAPIの定義方法
OpenAPI定義は下記のような形です、今回の例ではyaml
で定義していますがjson
でも定義可能です。
下記に詳しい説明が記載されています。
下記の例では、以下のAPIを定義したものです。
/foods
で食品の一覧を取得する/foods/{id}
で特定の食品を取得する
openapi: '3.0.2' # 使用するOpenAPIのバージョン info: # API定義全体の説明 title: 'FoodoList Api' version: '0.0.1' servers: # APIを返すサーバーの情報 - url: https://rails:3000 description: Development server paths: # ここにAPI定義のリストを書いていく '/foods': get: tags: - foods summary: Get all foods. description: Returns an array of Food model parameters: [] responses: '200': description: A JSON array of Food model content: application/json: schema: type: array items: $ref: '#/components/schemas/Food' # componentsに定義したスキーマ情報をロード example: - id: 1 name: sample1 memo: sample memo address: sample address image_url: https://example.com/sample1.png - id: 2 name: sample2 memo: sample memo address: sample address image_url: https://example.com/sample2.png '/foods/{id}': get: tags: - foods summary: find food. description: Returns an object of Food model parameters: - name: id in: path description: food id required: true schema: type: integer responses: '200': description: A JSON of Food model content: application/json: schema: type: object $ref: '#/components/schemas/Food' example: - id: 1 name: sample1 memo: sample memo address: sample address image_url: https://example.com/sample1.png components: # ここに個別のスキーマ情報を書く schemas: Food: type: object required: - id properties: id: type: integer name: type: string memo: type: string address: type: string image_url: type: string
Swagger UI
Swagger UIはOpenAPIの定義方法で記載したようなOpenAPIを使ったAPI定義から、きれいなAPIドキュメント生成するツールです。
下記のようなきれいなAPI定義書を生成することができます。
Docker環境も用意されていて、環境変数SWAGGER_JSON
に定義ファイルのパスを指定することで生成するAPI定義書の元となるファイルを制御することができます。
https://hub.docker.com/r/swaggerapi/swagger-ui/
Swagger Editor
Swagger Editorは、OpenAPIの定義方法で記載したようなOpenAPIを使ったAPI定義をSwagegr UIでプレビューしながら書けるEditorです。Webでも使えるので、そちらから触ってもらったほうが早いと思います✍
詳しい使い方とかはこちら
OpenAPI Generator
OpenAPIを使ったAPI定義からstab用のアプリケーションを作成することができるツールです。
コマンドラインから使用するcli
とWebからGUIで使えるonline
の二種類があります。
stabを生成できるアプリケーションは、rails、sinatra、ruby、python、php、perl、elixirなど様々で詳しくは下記を参照してください。
使い方はnpmやhomebrew、Dockerで環境を構築するとopenapi-generator-cli
コマンドが使えるようになります。
実際にstabを生成するコマンドの例は下記のような感じです。
$ openapi-generator generate -i /openapi-repo-name/openapi.yml -g stab-app -o /openapi-repo-name/stab-app-name
各オプションは下記のような感じ
実際に生成してみたのですが、私の定義が悪いのかもですがexampleをいい感じに返してくれるわけではないみたいですね(・・;)※生成するアプリケーションのフレームワークの種類にもよるのかもですが。。。
class FoodsController < ApplicationController def index # Your code here render json: {"message" => "yes, it worked"} end def show # Your code here render json: {"message" => "yes, it worked"} end
おわりに
OpenAPIや関連ツールについてまとめてみました。 実際の業務ではOpenAPIで定義して、Swagger UIでドキュメント化し、CIで定義ファイルが変更するたびにOpenAPI GeneratorでStabを生成してECR とかに上げて自動的にstabアプリケーションが更新されていくような仕組みを作ると良さそうですね👍
さくっと試したい人は環境を作っているので、下記から試してみてください。