[キャッチアップ] Swagger / OpenAPI
概要
だいたいこの辺 の内容を押さえて試してみる
OpenAPI
OpenAPI Specification は、 REST API インタフェースを記述するための標準フォーマット
APIインタフェースには以下のものを含む
- 有効なエンドポイント名とメソッド(GET, POST, ...etc)
- 入力パラメータと出力データ構造
- 認証方法
- 連絡方法、ライセンス、利用規約などのメタ情報
OpenAPI は、YAML または JSON で記述することができ、人間にも機械にも理解しやすい上、学習コストも低いフォーマットなのが特徴
Swagger
Swagger は、 OpenAPI Specification のためのオープンソースのツールセット
Swagger は開発者のAPI設計、構築、ドキュメンテーションの支援をする他、API利用者がAPIを容易に利用するための仕組みも内包されている
主要な Swagger ツールには以下のものがある
- Swagger Editor: ブラウザ上で OpenAPI を記述できる
- Swagger UI: OpenAPI のドキュメントを生成する
- Swagger Codegen: OpenAPI に基づいてサーバサイドのスタブまたはクライアントサイドのライブラリを生成する
OpenAPI / Swagger を使うメリット
-
Swagger Codegen
をサーバサイドで用いることで、設計ファーストの API を半自動で構築でき、あとはサーバサイドのロジックを記述するだけで API を完成させることができる -
Swagger Codegen
をクライアントサイドで用いることで、クライアント側で独自にAPIの定義をしなくてもすぐに利用することができる -
Swagger UI
を、APIのユーザーが用いることで、すぐにインタラクティブにAPIの動作を試すことができる
Open API の基本構造
OpenAPI は 以下のフィールドを持った JSON または YAML で記述する
openapi
使用する OpenAPI のバージョンを指定する
openapi: 3.0.0
info
API の基本情報を記述する
info:
title: tweeter API
description: Twitterっぽい何か
version: 0.0.1
servers
API を提供するサーバを記述する。ここで指定した URL が、各エンドポイントの BaseURL になる
servers:
- url: localhost:3001/api
description: ローカル環境
paths
エンドポイントごとに仕様を記述する
ここでは細かい構文は割愛するが、リクエストパラメータやレスポンスパラメータなど、OpenAPI の仕様に沿って正確に記述する必要がある
paths:
/users/{id}:
get:
summary: 指定したユーザの情報を取得する
parameters:
- name: id
in: path
required: true
description: 対象のユーザID
schema:
type: integer
format: int64
minimum: 1
responses:
'200':
description: ユーザーオブジェクト
content:
application/json:
schema:
type: object
properties:
id:
type: integer
format: int64
example: 4
name:
type: string
example: 'sasaki'
displayName:
type: string
example: 'ささき'
データモデルを再利用する
例えば ユーザ一覧(/users
) と ユーザー閲覧(/users/{id}
) で返されるユーザー情報の構造が同じである場合、繰り返し同じデータ構造を記述するのでなく、一箇所に記述して再利用したい
そういう場合は components
を利用する
components:
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
example: 4
name:
type: string
example: 'sasaki'
displayName:
type: string
example: 'ささき'
参照するときは $ref
を用いる
responses:
'200':
description: ユーザーオブジェクト
content:
application/json:
schema:
$ref: '#/components/schemas/User'
データモデルを再利用する
例えば ユーザ一覧(/users
) と ユーザー閲覧(/users/{id}
) で返されるユーザー情報の構造が同じである場合、繰り返し同じデータ構造を記述するのでなく、一箇所に記述して再利用したい
そういう場合は components
を利用する
components:
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
example: 4
name:
type: string
example: 'sasaki'
displayName:
type: string
example: 'ささき'
参照するときは $ref
を用いる
responses:
'200':
description: ユーザーオブジェクト
content:
application/json:
schema:
$ref: '#/components/schemas/User'
vscode から使う
Swagger Editor
や Swagger UI
が公式から提供されているが、これらと同等のことが vscode 拡張で充分できる上、豊富な追加機能があるのでこれで充分そう
Swagger Codegen
Swagger Codegen(GitHub) は、 OpenAPI Spec を元に、ドキュメントの生成、スタブサーバの構築、及び様々なプログラミング言語向けの API クライアントの生成を行うツール
インストール
いくつかのインストール方法があるが、今回は Mac を使用しているので、brew でインストールする
$ brew install swagger-codegen
インストールできてることを確認
$ swagger-codegen --help
usage: swagger-codegen [-h] Command ...
named arguments:
-h, --help show this help message and exit
commands:
Command additional help
generate generate
config-help config-help
meta meta
langs langs
version version
HTML ドキュメントを生成する
ドキュメントを静的HTMLとして出力することで、容易に配布したり出来るようにする
$ swagger-codegen generate -i doc/index.yaml -l html -o docs
見た目がイマイチなので他の HTML ジェネレータを使ったほうが良いかも
Swagger Specから静的なHTMLを作るHTMLジェネレータを色々ためしてみた
JavaScript クライアントを作る
今回は JavaScript から使えるクライアントを用意したいので、以下のコマンドを実行する
$ swagger-codegen generate -i doc/index.yaml -l javascript -o mysdk
mysdk
ディレクトリに、クライアントライブラリが自動でできあがる
$ tree mysdk/
mysdk/
├── README.md
├── docs
│ ├── Body.md
│ ├── DefaultApi.md
│ ├── InlineResponse400.md
│ ├── OneOfinlineResponse400Message.md
│ └── User.md
├── git_push.sh
├── mocha.opts
├── package.json
├── src
│ ├── ApiClient.js
│ ├── api
│ │ └── DefaultApi.js
│ ├── index.js
│ └── model
│ ├── Body.js
│ ├── InlineResponse400.js
│ ├── OneOfinlineResponse400Message.js
│ └── User.js
└── test
├── api
│ └── DefaultApi.spec.js
└── model
├── Body.spec.js
├── InlineResponse400.spec.js
├── OneOfinlineResponse400Message.spec.js
└── User.spec.js
7 directories, 21 files
あとはだいたいこんな感じで使える
var TweeterApi = require('tweeter_api');
var api = new TweeterApi.DefaultApi()
var id = 789; // {Number} 対象のユーザID
var callback = function(error, data, response) {
if (error) {
console.error(error);
} else {
console.log('API called successfully. Returned data: ' + data);
}
};
api.usersIdGet(id, callback);