🤔

OpenAPIの書き方に迷ったときに読む記事

2023/01/21に公開約5,400字

API開発をするにあたり、OpenAPIも書くことがセットとなりつつある。

OpenAPIを初めて書いたとき、既存の実装から書き方を真似てみたり、時にはGoogleで検索して書き方を調べながら進めていた。

しかし、それがベストな書き方かわからず、より良い書き方を模索していくうちに公式ドキュメントを読み込むことに。

そこで気づいたことは今まで調べていたことは、二番煎じどころか何番煎じかもわからない情報を参考にしていたということ。

それらの情報は公式ドキュメントをまとめたものかも知れないし、はたまたネット記事から得た情報をただ書き起こしたものかも知れない。

公式ドキュメントの情報量は正確であるがゆえに膨大なので、まとめ記事は概要を把握するには適している。

だが、書き手の中で情報が選別されてしまっており、本当に必要な情報が削ぎ落とされている可能性も捨てきれない。

本記事では公式ドキュメント[1]やOpenAPI Map[2]の活用法を紹介する。

この記事の対象者

  • OpenAPIを書いているが、より良い書き方を模索している方
  • これからOpenAPIを書き始めようとする方

OpenAPIで表現できること

公式ドキュメント[1:1]を読めば何を表現できるか全て書いてあるが、上から順に読み進めようと思ってもあまりの量に「うっ..」となってしまう。

そこでまず抑えるところはOpenAPIのルート情報である。

フィールド名 説明
openapi 必須項目。OpenAPIドキュメントが使用している OpenAPI Specification のバージョン番号を指定する必要がある。 openapiフィールドは、ツールが OpenAPI ドキュメントを解釈するために使用されるべき。これはAPI自体のバージョンを示す info.version とは関係ない。
info 必須項目。APIに関するメタデータを提供する。このメタデータは、必要に応じてツールで使用してもよい。
jsonSchemaDialect このOASドキュメントに含まれるスキーマ・オブジェクト内の $schemaキーワードのデフォルト値。これはURI形式でなければならない。
servers ターゲットサーバへの接続情報を提供する。 serversプロパティが指定されていない場合、あるいは空の配列の場合、 デフォルトは / のサーバオブジェクトとなる。
paths API で利用可能なパスとオペレーション。
webhooks このAPIの一部として受信する可能性があり、APIコンシューマが利用することもある受信Webhooks。 callback機能と密接に関連し、このセクションではAPI呼び出し以外によって開始されるリクエストを記述する。キー名は各webhookを参照するための一意な文字列で、Path Item ObjectはAPIプロバイダによって開始されるかもしれないリクエストと期待されるレスポンスを記述する。サンプル
components ドキュメントに関する様々なスキーマを保持するための要素。
security API全体でどのセキュリティ機構を使用できるかを宣言したもの。値のリストには、使用可能な代替のセキュリティ要件オブジェクトが含まれている。リクエストを承認するためには、セキュリティ要件オブジェクトのうち1つだけが満たされる必要がある。個々の操作は、この定義を上書きすることが可能。セキュリティをオプションにするには、空のセキュリティ要件 ({}) を配列に含める。
tags ドキュメントで使用されているタグのリストと、追加のメタデータ。タグの順序は、解析ツールによる順番に反映させることができる。Operation Objectが使用するすべてのタグを宣言しなければならないわけではない。宣言されないタグは、ランダムに、またはツールのロジックに基づいて整理してもよい。リスト内の各タグ名は一意でなければならない。
externalDocs 外部資料。

[引用元]:https://spec.openapis.org/oas/v3.1.0.html#openapi-object

引用元の公式ドキュメントを見たらわかるように、ドキュメントの大部分が4.8 Schemaのことで占めている。

また、これら全部に目を通す必要はなく、ルート情報(OpenAPI Objectという)から必要そうなフィールドだけを深堀りするだけでよい。

そう考えると公式ドキュメントを読むのもイケそうな気がする。

上記で挙げたルート情報からいくつかフィールドを読み解いてみよう。

paths

API開発者はpathsを書けるようになることは必須事項だろう。

pathsにはエンドポイントへの相対パスを記述できる。

そのpathsで注意すべきなのはマッチングのルールのみである。

例えば、下記のように定義されていた場合。

paths:
  /pets/{petId}:
    :
    :
  /pets/mine:

2つ目に定義している/pets/mineにはマッチングせず、最初の/pets/{petId}にマッチングされる、と当たり前のことが書かれている。

pathsオブジェクト

さらに深堀りしていくとpathsにはPath Item Objectが指定でき下記のように記載できることがわかる。

openapi.yml
 /pet:
    put:
      tags:
        - pet
      summary: Update an existing pet
      description: Update an existing pet by Id
      operationId: updatePet
      requestBody:
        description: Update an existent pet in the store
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
        required: true

Path Item Objectのフィールドには$refが含まれているので、下記のようにファイルを分割して書くこともできる。

openapi.yml
  /pet:
    $ref: ./paths/pet.yml
pet.yml
put:
  tags:
    - pet
  summary: Update an existing pet
  description: Update an existing pet by Id
  operationId: updatePet
  requestBody:
  description: Update an existent pet in the store
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/Pet'
  required: true

もし$refについて知りたいときは$refの説明に詳細な説明が記載されている。

components

pathsで少し触れたが、1ファイルに全てのAPI情報を記載すると情報が多くなりすぎるので、レスポンス情報などを共通化したり、ファイル自体を分けて書きたいケースがある。

そういったケースでcomponentsを利用する。

再利用可能なオブジェクトのセットを保持、つまり変数のように定義を使い回すことができる。

componentsで定義されたオブジェクトは、componentsの外のプロパティから明示的に参照されない限り、APIに影響を及ぼさない。

componentsオブジェクト

どのように分割するかはチームの方針や個人の好みにもよるところがあるので、チーム開発する際には事前にルールを決めておく必要がある。

servers

最後にservers

serversにはSwagger UIからリクエストするサーバ情報を記載することができる。

例えば

  • 開発環境
  • ステージング環境
  • 本番環境

上記3つの環境のAPIをSwagger UIで試したい場合、下記のように記載することで簡単にリクエスト先を切り替えることができる。

servers:
- url: https://development.gigantic-server.com/v1
  description: Development server
- url: https://staging.gigantic-server.com/v1
  description: Staging server
- url: https://api.gigantic-server.com/v1
  description: Production server

serverオブジェクト

Swagger UIでリクエストできるデモページが用意されているので、使い勝手を知りたい人は試してみよう。

https://editor.swagger.io/

Swagger UIでリクエストしている様子

OpenAPI Map

最後に紹介したいのがOpenAPI Map

公式ドキュメントより直感的にフィールドを確認できるツールである。

https://openapi-map.apihandyman.io/

マインドマップのように特定の要素をクリックしていくとそれに紐づくフィールドが展開され、その内容が確認できる。。


OpenAPI Mapでフィールドを確認している様子

これがあれば公式ドキュメントが不要と思うかも知れないが、残念ながら最新の情報に追従できてないので、今回おまけとして紹介している。

おわりに

OpenAPIについて調べているとcopomentを分割したり、ファイルを分割したり様々な手法が紹介されている。

しかし、そういった手法にはチームやPJの背景、つまりメンバー個々のスキルや業務内容などセンシティブな内容が絡んでいる場合もある。

それらの情報を全て公開するのは難しいため、当たり障りない部分だけに触れ、実践方法を中心に紹介されているかも知れない。

どんな場面でもベストな書き方はないので、まずはOpenAPIを包括的に理解し、状況に応じた書き方を知ることがOpenAPIを使いこなす第一歩だろう。

脚注
  1. https://spec.openapis.org/oas/v3.1.0.html ↩︎ ↩︎

  2. https://openapi-map.apihandyman.io/ ↩︎

Discussion

ログインするとコメントできます