🎯

OpenAPIを棚卸しする(3.0.x)

2022/07/18に公開

はじめに

社内で技術的な共有として、それなりに業務経験のある OpenAPI を題材にしてみようと考えた時に、
スライドを作成する前に、用語などを整理するために2021年に記事を書き起こした。

関連用語

単語 説明
OpenAPI OpenAPI Specification に従った各種ツール群などの通称。記載された json/yaml もしくは Swagger-UI のことを一般的に指すと思う。
OpenAPI Specification OpenAPIの仕様です。APIの記述形式を指しています。この記述形式に従って定義書を書く事で、仕様に従った各種ツールと連携できる。略すと OAS らしい。
Swagger OpenAPIの前身。 Swagger を取り巻いていた後述のツールなどは現在もメンテされている。
Swagger Editor OpenAPI Specification に従ったファイルをウェブブラウザで編集できるエディター。 docker でも配られていたりする。
Swagger UI OpenAPI Specification に従ったファイルをウェブブラウザで描画するツール。 docker でも配られていたりする。
OpenAPI Generator OpenAPI Specification に従ったファイルから色々生成するツール。
Web API Web技術を用いて提供されているAPI
RESTful API RESTに従って設計された Web APIOpenAPI SpecificationRESTful API を対象としている。
(Web)API仕様書 APIの仕様書。
エンドポイント URIHttpMethod の組み合わせ。
オープンAPI 公開されているAPIのこと。プライベートの逆。パブリックAPIとも呼ぶ。
(API)スキーマ どこにどんなリクエストを送るとどんなレスポンスが返ってくるかの取り決めのこと。
スキーマ駆動 APIの利用者と提供者が一緒になってスキーマの設計を行い、スキーマありきで開発をすすめる手法のこと。

OpenAPIってなにを解決するツールなの?

私達が抱える課題

  • API仕様書が 在るべきところにない/集約していない/見つけられない
  • API仕様書のフォーマットが揃っていない(≒読み方をフォーマット毎に理解しないといけない)
  • APIを一発実行しようとする時にパラメータのサンプルがない、実行できるデータの準備が必要
  • API仕様書と実装が乖離している、メンテナンスが追いついていない
私が抱えていたストレスポイント
😆 「商品情報を引っ張りたいんだけど、商品情報取得APIみたいなのあるかな?仕様書どこだろう」
😅 「仕様書がWordファイルなんだけど、最終更新が5年前、、、この仕様書はマスタなのだろうか、最新なのだろうか」
😓 「APIを一発叩いてみようと思うけど、パラメータ指定するのめんどくさいな。」
😢 「別のAPI叩こうとしたら仕様書のフォーマット違ってて辛い。」
😩 「APIを叩いてみたら仕様書通りのレスポンスが返ってこない。」

OpenAPIはなにを実現/解決できるのか

OpenAPI Specification

  • 定義ファイルの中身は json/yaml なので、メモ帳/テキストエディターで閲覧/編集可能
    OpenAPI は各種支援ツールが豊富なので VS Code などのプラグインも有
    Swagger Editor でpreviewしながら編集も可能。
  • バージョン管理が容易、編集/変更履歴/仕様変更/変更差分などが追跡しやすい
  • チーム内で標準化しやすい。
    OpenAPI Specification でネットで調べると記述方法がhitする
  • 繰り返し出現する要素を共通化することにより仕様書の記述コストを下げることが可能
    ※ difinitionsに集約することで、一箇所修正すれば使用箇所は全て反映される

Swagger UI

  • 定義した json/yaml がヒューマンリーダブルに描画される
  • パラメータが example value に従って自動生成されるのでAPIの一発実行もフランクに行える
  • API実行ツールを内包している
    ※ 中身はcurl
  • httpで公開できるので、ブラウザで遠隔からアクセスできる
    ※ 共有ファイルサーバなどでも実現可能ではあるが。。。。

定義ファイルからの自動生成

  • 自動化テストの作成補助
  • モックサーバの用意
    ※ モックを用意すれば、フロント側の開発が着手できる
  • 実装(プログラム)の一部自動生成
    ※ 仕様書と実装のインターフェースが完全に揃う
    ※ 提供/利用側もどちらも対象
  • PostmanなどのAPIクライアントツールでのテストリクエストimport機能
    ※ めんどくさいテストもこの機能で負担を軽減できそう
    ※ APIクライアントツールのテストリクエストをエクスポートして配ればなお良し

ツールだけで解決できないこと

  • API仕様書を 在るべきところにおく
     ※ 目につきやすい所に Swagger-UI のリンク貼っておこう、布教しよう
  • APIをサンプルで用意されているパラメータで叩いても正常系が返ってこない
     ※ サンプルを工夫するか、データに依存しないように実装自体をいじってしまおう
  • API仕様書からプログラムの全自動生成
     ※ NoCodeとまでは言えない、API仕様書と実装が乖離しないように絶えずメンテが必要

類似ツール

  • API Blueprint
  • Carte
  • RAML

Swagger-UIで見てみよう

早速書いてみよう!よりも先に書いた後どうなるかをさらっと記載する。

閲覧する人

  • APIを提供する側
  • APIを利用する側
背景
まずはAPI仕様書を参照する読者を考えてみる。
もちろん開発者(提供者)自身が書いて、読み返すことが考えられる。
APIの利用者が読むわけで、利用パターンは
- バックエンド -> バックエンド
- フロントエンド -> バックエンド
が考えられ、バックエンドエンジニアとフロントエンドエンドエンジニアが存在する。
APIを外部公開して収益を挙げる場合、販売する営業さんも見るかもしれない。
となると、開発に関わるエンジニア以外も見るケースがあるかもしれない。

OpenAPIの構成

sample(petstore)を例に大きな要素を箇条書きする。
※ OpenAPI 3.0の仕様で記載する

Explore

入力欄に描画したい json/yaml ファイルのパスを指定し、
Exploreボタン を押下することでAPI仕様書を切り替えることができる。
正直使わない。

info , servers , security

描画中のAPI仕様書の概要、サーバー情報などが表示される。
またAPIアクセスに認証などが必要だった場合は、 Authorizeボタン から情報を入力すると、
API実行時に自動でリクエストヘッダなどに値を設定してくれる。

tags , paths

tag -> path の順でソートされており、
tag -> description(説明) , operation/path -> summary(概要) を1行で出力している。
tag は エンドポイント群をグルーピングしており、意味のある塊として扱っている。
APIは operation/path で1行であり、 operation(HTTP method) 毎に色が分けられている。
※ DELETEは赤色で、触ったらいけない感を演出しているように見える
operation/path を展開すると、 description , Parameters , Responses で分かれていて、 Try it outボタン がある。
Try it outボタン を押下すると入力欄が活性化され、
さらに Executeボタン を押下することでAPIに入力値を送出することができる。

Models

API仕様書内で構造化したオブジェクトの一覧を並べている。
200以外のレスポンスなどは、実装時にフレームワークなどで統一したものを返却するので、
そういった共通のオブジェクトが並んでいたりする。

OpenAPI Specificationに従って書いてみる

json/yamlで記載する。どちらもたいして優位性は変わらない。
初心者はyaml推奨。Swagger-Editorのサンプルがyamlなので。
$ref を使用すると、ファイルを参照させることができ、ファイル単位で切り出せたりできる。

エディター

  • VS Code (Swagger Viewer)
  • Swagger Editor
  • Stoplight Studio

OpenAPIの構成

仕様書として必要最低限のものを並べてみる。
公式の並び順ではなく、

  • info
  • servers
  • tags
  • paths
  • components
    の順に並べる。

API情報

APIの情報を定義するフィールド。

property value required array
openapi OpenAPI Specification のバージョン
info APIの情報 詳細
[Info].title APIの名前
[Info].description APIの説明
[Info].version APIのバージョン

<details><summary>コード</summary><div>

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT

</div></details>

サーバー情報

サーバーの情報を定義するフィールド。
servers は必須ではないのでなくてもいい。

property value required array
servers APIのサーバー情報 環境毎に定義したりする 詳細
[Server].url APIのURL
[Server].description URLの説明

<details><summary>コード</summary><div>

servers:
  - url: http://petstore.swagger.io/v1

</div></details>

Tag情報

タグの情報を定義するフィールド。
エンドポイントをグルーピングし、意味のある塊として扱うために定義する。

property value required array
tags タグの情報 詳細
[Tag].name タグの名前
[Tag].description タグの説明

エンドポイント

エンドポイントの情報を定義するフィールド。
これがメイン。

property value required array
paths エンドポイントの情報 詳細
[Path].parameters パス内のパラメータなどを定義する [Path].[Operation]配下まで適用される 詳細
[Path].[Operation] HttpMethod get , post , put , patch , delete などのいずれか 詳細
[Path].[Operation].tags エンドポイントの所属するタグ
[Path].[Operation].summary エンドポイントの概要 Swagger UI では1行で表示される
[Path].[Operation].description エンドポイントの説明
[Path].[Operation].operationId エンドポイントのユニークID
[Path].[Operation].parameters エンドポイントのパラメータなどを定義する 詳細
[Path].[Operation].requestBody エンドポイントのリクエストボディ 詳細
[Path].[Operation].responses エンドポイントのレスポンス [HTTP Status Code]毎に定義する 詳細
property value required array
[Parameter].name パラメータの物理名
[Parameter].in パラメータの種別 query , header , path , cookie のいずれか
[Parameter].description パラメータの説明
[Parameter].required パラメータが必須か否か  true , false のいずれか
property value required array
[RequestBody].description リクエストボディの説明
[RequestBody].required リクエストボディが必須か否か  true , false のいずれか
[RequestBody].content リクエストボディの内容 詳細
[RequestBody].[MediaType].schema 詳細
property value required array
[Response].description レスポンスの説明
[Response].content レスポンスの内容 詳細
[Response].[MediaType].schema 詳細

共通オブジェクト

共通のオブジェクトなどを切り出して定義するフィールド。
200 OK 以外の 400 Bad Request などの汎用的に使いまわせるオブジェクトなどを定義する。
$ref を使って参照させる。

property value required array
components 詳細
component.schemas 詳細
component.responses 詳細
component.parameters 詳細
component.requestBodies 詳細
component.headers 詳細

てっとり早く書いて公開するためには?

OpenAPI Specificationversion3.0 基準で書かれている/公開されているものの json/yaml を引っ張ってきて、
参考に書き換えていけば良さそう。

sample(petstore)version2.0 なので、このまま使うと古い仕様になってしまう。
Githubに公開されているversion3.0は参考にできそう。

工夫して書こう

  • description にHTMLを使って説明をリッチにする
  • プロパティの定義(型/length/定数/文字種別)は堅牢に

<details><summary>背景</summary><div>
API仕様書に処理の詳細を書く必要は無いが、1行だけの説明だと味気ない。
データに依存するような仕様が存在した場合は、是非書いておこう。
テーブル表記などはHTMLで表現できる。

永続化されている/するパラメータについては、リソースの設定に依存される。
例えば、MySQLの int(unsigned)0~4294967295 の範囲。
範囲外のものは永続化できないし、そもそも文字列などは指定できない。
この場合、API仕様書では

type: integer
minimum: 0
maximum: 4294967295

のように定義できる。
リソースの仕様も設計時に事前の確認が必要そう。

氏名(カナ)を登録/更新などする際は、

type: string
pattern: '[ァ-ヶ]*'

のように定義できる。
</div></details>

OpenAPIを使ったWebAPI開発について

どんな感じで開発していくか考えてみた。

  1. OpenAPIをチームで書くための準備をする
     ※ チームがコミットできるようにGithub/Gitlabにリポジトリを用意する
     ※ エンドポイント以外の骨組みを定義し終え、Swagger Editor でエラーがでない状態にしておく
     ※ Swagger UI サーバーをたてる(Gitlabだと内包しているので別途用意する必要なし)
  2. 設計を進める/OpenAPIを書く/レビューする/OpenAPIを更新する
  3. OpenAPIから色々自動生成できるように技術調査/用意をすすめる
     ※ モックサーバの用意
     ※ 実装(プログラム)の一部自動生成
  4. OpenAPIの完成
  5. モックサーバの準備
     ※ サーバの用意
     ※ OpenAPIが更新された場合、モックサーバ側のファイルの更新をどうするかの確認
  6. WebAPI実装の準備
     ※ OpenAPIが更新された場合、自動生成ファイルも更新できるかなどの確認
  7. WebAPI実装の着手/OpenAPIの修正
     ※ 実装がすすんだ際の仕様変更/方針の反映
     ※ OpenAPIが更新された場合の連絡/周知などの徹底
  8. WebAPI実装の完了/テスト実施完了
     ※ APIクライアントツールでOpenAPI取り込み
     ※ APIクライアントツールでテスト実施

こんな感じになるかなぁと。
色々とCIに組み込めたりすると、最初は準備が大変だけど保守は楽になるかなと思う。

Discussion