🏃

Swagger v3を使ってみよう!

2022/12/22に公開

これは CAMPHOR- Advent Calendar 2022 の22日目の記事です。
実際のソースを見ながらswagger version3を使ってみようという記事です。
主に

  • 柔軟性のある(?)ディレクトリ構成の紹介。ほんまか?
  • 複数ファイルに切り出した場合の記述方法
  • headersに入れる要素を定義するには?

について話しています。
API設計はYAMLで書いています。
YAML内で使用するフィールドについては他の記事で説明されているので書いていません。

この記事を書いた経緯

  • swagger入門した時にv2について書かれた記事は多かったもののv3について書かれた記事が少なかった(ゆーても記事内ではv2とv3の違いはsecurityフィールドしかない)
  • 複数ファイルに切り出したswaggerの書き方についての記事が少なかった
  • アドカレのネタを考えている内に「swagger v3関連の記事を書くのです書くのです書くのでs」という天の声を聞いた

swaggerとはなんぞ?

RESTful API設計のためのツールで、設計・文書化・テスト・デプロイなどを行うことができるものです。
個人的には以下のケースで重宝される気がしています。

  • フロントエンド、バックエンドのチームが分かれているとき
  • 使用技術が決まっていない段階でAPI設計したいとき
  • 外部向けにAPI設計を公開したいとき
  • OpenAPIからサーバー・クライアントのコードを自動生成したいとき

今回使うサンプルのソース

https://github.com/shosho44/swagger-sample
2つのエンドポイントを用意しました。
それぞれPOSTとGETに対応しています。

ディレクトリ構成

大まかなディレクトリ、ファイルの説明


swagger.yaml

docker-compose.yamlが参照しているファイルです。
このファイルはpathsを参照しています。


paths

「APIの各エンドポイント、response headerに格納するセキュリティの項目、response headerに格納して返す要素の具体例、response bodyに格納して返す要素の具体例」
が書いているファイルを置くディレクトリです。
pathsに置かれたファイルはcomponentsを参照しています。


components

authorized

認証が必要な各APIのrequest bodyまたはresponse bodyに格納する要素と具体例が書かれているファイルを置くディレクトリです。

headers

response headerに格納する要素について書かれているファイルを置くディレクトリです。

not-authorized

認証が不要な各APIのrequest body または response bodyに記述する要素と具体例が書かれているファイルを置くディレクトリです。


dockerで実際に動かしてみよう

make run

後にブラウザで
http://localhost:8011/
にアクセスしてください

上の画面が出てくるので

try it outボタンを押して

を押してリクエストとレスポンスを確認してみましょう

各フィールドの意味

フィールドの説明は以下の記事が詳しいので、ソース内でわからないフィールドがあればご参照ください。
https://qiita.com/teinen_qiita/items/e440ca7b1b52ec918f1b
https://qiita.com/halhorn/items/e47673eecc4a01ffb3a0

複数ファイルに切り出した際の記述方法

swagger.yamlとpaths/company/register.yamlを例に紹介します。

swagger.yaml
paths:
  /api/v1/company/register:
    $ref: './paths/company/register.yaml#/paths/~1company_register'
paths/company/register.yaml
paths:
  /company_register:
    post:
      security:
        - bearerAuth: []
      tags:
        ............

swagger.yamlからpaths/company/register.yamlのcompany_registerの定義を読み込んでいます。
見ての通りですが、

./paths/company/register.yaml

がswagger.yamlからのregister.yamlまでの相対パスで

#/paths/~1company_register

でregister.yaml内のcompany_registerフィールドを指定しています。

headersに入れる要素を定義するには?

response headerの場合

swagger.yaml
components:
  securitySchemes:
    bearerAuth:
      scheme: bearer
      type: http
      bearerFormat: JWT
security:
  - bearerAuth: []
paths/company/register.yaml
responses:
  '200':
    description: '200'
    security:
      - bearerAuth: []
    headers:
      $ref: '../../components/headers/status-code_error-message.yaml#/components/schemas/Headers200'

headersフィールドに定義したschemaを指定します。
ただ、この方法だとデフォルトがnullになってしまう問題があります。
このやり方以外のresponse headerの定義方法を知っている方がおられたら教えていただけるとありがたいです。
JWTのように認証のためのトークンをheaderに入れたい場合は、securitySchemesを作成してsecurityフィールドに指定します。

request headerの場合

paths/company/register.yaml
paths:
  /company_register:
    post:
      security:
        - bearerAuth: []
      tags:
        - company/register
      operationId: postCompanyRegister
      requestBody:
        content:
          application/json; charset=utf-8:
            schema:
              $ref: '#/components/schemas/RegisterCompanyRequest'

認証のためのトークンを入れたい場合は、swagger.yamlで定義したフィールドをsecurityフィールドに指定します。
MIMEタイプの指定も見たまんまですがcontentの内部に指定するとできます。

おわりに

swagger書いている時も記事書いている時もheaderに要素指定する方法が他にあるじゃないかと思っているので、有識者はぜひ!ぜひともコメントかtwitterで教えていただけると嬉しいです!
次はstoplightについての記事を書きたいところです。

Discussion