何?Swaggerって?

お仕事で「APIの仕様書をすわっがーで作ってね」って言われました、既存の仕様書はYAMLファイルになっているのですが・・・何?Swaggerって?

Swaggerは、OpenAPI仕様に基づいてREST APIの仕様書作成から構築を助けてくれるツールです。

Swagger は RESTful APIを構築するためのオープンソースフレームワークのことです。「Open API Initiative」という団体がRESTful APIインターフェイスの記述をするための標準フォーマットを推進していて、その標準フォーマットがSwaggerです。Swaggerには多くの便利なツールが提供されていることもあり、多くのメリットを享受できそうです。

Swaggerの概要をまとめてみた。 - Qiita

仕様書のフォーマット?

Swaggerは、OpenAPI仕様(以下OAS)と言われる、REST APIを定義するための標準仕様にもとづいて構築された一連のオープンソースツールです。REST APIの設計、構築、文書化、および使用に役立つ機能を提供します。

本当に使ってよかったOpenAPI (Swagger) ツール | フューチャー技術ブログ

フォーマットだけじゃなくて、仕様書から構築までできるらしいです。

OpenAPIは、REST APIの記述フォーマットです。

What Is OpenAPI?

OpenAPI Specification (formerly Swagger Specification) is an API description format for REST APIs.

(省略)

What Is Swagger?

Swagger is a set of open-source tools built around the OpenAPI Specification that can help you design, build, document and consume REST APIs.

About Swagger Specification | Documentation | Swagger - swagger.io

弱い英語力から以下程度に解釈しました。

Swagger3.0は、OpenAPI?

OpenAPI は Swagger 3.0

Swagger 3.0 から OpenAPI に名前が変わったため、 OpenAPI 3.0 は Swagger 3.0 でもあります。

もともと他にも API 周りのインターフェース定義ができるルールが存在してたのですが、 Swagger が晴れて標準となったようです。 他には API Blueprint などがあるようですが、僕もそこまで詳しくはありません。 OpenAPI の仕様の、現時点での最新は 3.0.2 です。 仕様書はこちらにあります。

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md

OpenAPI (Swagger) の基本的なあれこれ - ばうあーろぐ

Swaggerは、2から3でなにやらずいぶん変わったようですが・・・初めてなのでとにかくSwagger3.0を使えるようになることを優先します。

ブラウザで仕様書を見て書けます。

ツールをインストールしたり環境を構築したりしなくてもすぐに使えそうです。

  1. Swagger Editorをブラウザで表示する
    • f:id:ponsuke_tarou:20210121141523p:plain
  2. [File] > [Import file] > 既存の仕様書をインポートする
    • f:id:ponsuke_tarou:20210121141129p:plain
  3. 仕様書に定義されたインターフェースが横に見やすく表示された!
  4. 左のYMLを修正すると右側に反映される

実行もできます。

呼出し先が起動していれば、必要な情報を入力して実行することもできました。

  1. 仕様書のAPIを起動して接続できるようにする
  2. f:id:ponsuke_tarou:20210121094641p:plain
    このボタンを押下すると入力できるようになる
  3. ヘッダやパラメータなど必須になっている項目を入力する
  4. f:id:ponsuke_tarou:20210121094746p:plain
    このボタンで実行できる
  5. 「TypeError」になったけれどAPIのログを見てみるとちゃんとAPIを呼び出していた
    • f:id:ponsuke_tarou:20210121142535p:plain
      Server responseにAPIからのレスポンスが表示される

GitにあるSwaggerのファイルをプレビューできるChrome拡張機能があるらしいです。

qiita.com

f:id:ponsuke_tarou:20210122223424j:plain
板橋区の梅の湯

Serversを書く

APIのサーバを定義します。 サーバには、本番環境やらテスト環境など複数を定義できます。

認証を書く

試しに「OAuth2.0で取得したBearerのトークンをヘッダにAuthorizationで設定する」みたいに書こうとした・・・ら、なんか言われました。

Header parameters name "Authorization" are ignore. Use the `securitySchemes` and `security` sections instead to define authorization.

f:id:ponsuke_tarou:20210121161236p:plain どうやら、ヘッダやパラメータに「Authorization」を設定しても無視されるようです。

You have used a restricted value as the name of a header parameter. The values Accept, Content-Type, and Authorization are restricted values and should not be used as the header name. A header with any of these values as the header name is ignored.

Header parameter with the name 'Authorization' is ignored - apisecurity.io

では、どう書くのか?調べながら書いてみました。

Bearer スキームを書く

トークンを利用した認証・認可 API を実装するとき Authorization: Bearer ヘッダを使っていいのか調べた - Qiitaを読むとやりたいことは「Bearer スキーム」というものでした。

共通で使うオブジェクトや構造の定義を書く

APIのパラメータやレスポンスで共通のオブジェクトや構造を使うことがあります。 そんな共通のオブジェクトや構造は、components配下に定義して$refを使うことで参照できます。

Components Section

Often, multiple API operations have some common parameters or return the same response structure. To avoid code duplication, you can place the common definitions in the global components section and reference them using $ref.

Components Section - swagger.io

リクエストを書く

各リクエストのエンドポイントは、paths配下に定義していきます。

paths:
  /{エンドポイント}:
    summary: {短い説明文}
    description: >
      {長い説明文、
        ここにはMarkdownで複数行にわたって書くことができます。}

typeに定義するデータ型は、Data Typesに記載されているものを使用します。 |type|意味|参考になりそうなサイト| |:--|:--|:--| |string|文字列|| |number|整数と浮動小数点付き数値|浮動小数点って何? - Qiita| |integer|整数|| |boolean|真偽値|| |array|配列|| |object|オブジェクト||

パラメータを定義する

Describing Parameters

In OpenAPI 3.0, parameters are defined in the parameters section of an operation or path. To describe a parameter, you specify its name, location (in), data type (defined by either schema or content) and other attributes, such as description or required.

Describing Parameters - swagger.io

パラメータといっても種類があります。基本の書き方は同じで- inに指定する値を変えて書き分けます。各パラメータがどんな感じのものかはSwaggerの上記ドキュメントページにサンプルがあってわかりやすいです。

パラメータの種類 inに指定する値 参考になりそうなサイト
パスパラメータ path
クエリパラメータ query
ヘッダパラメータ header HTTP ヘッダー - HTTP | MDN
Cookieパラメータ cookie

フォーマットはこんな感じです。

parameters:
  - in: pathかqueryかheaderかcookie
    name: パラメータ名やヘッダのフィールド名
    schema:
      type: パラメータの型
      enum:
        - パラメータの値が特定の値しか受付ない場合に指定する
      example: パラメータの例
    required: 必須かどうかをboolで指定、パスパラメータは省略できないのでtrueを指定する
    description: パラメータの説明文
    allowEmptyValue: パラメータ名の指定のみで値がなくてもいいかどうかをbookで指定する

レスポンスを書く

Describing Responses - swagger.ioを参照すると、 各レスポンスは以下のようにresponses配下にHTTPステータスコード毎に定義していくようです。

responses:
  {ステータスコード}:
    description: {説明}
    content:
      {メディアタイプ}:
        schema:
          # ここからレスポンスボディを定義する
          type: {レスポンスボディのタイプ「object」「array」}
          properties:
            {プロパティ名}:
              type: {プロパティのタイプ}
              description: {プロパティの説明}

レスポンスのexampleを複数定義する

APIのレスポンスで同じHTTPステータスにexampleを複数定義したいということがあります。そんな場合の書き方です。

Adding Examples - swagger.ioを参考にするとフォーマットはこんな感じです。

paths:
  #...省略...
  responses:
    'HTTPステータスコード':
      #...省略...
      examples: # <<<複数定義する場合は「example」ではなく「s」をつけて「examples」になります。
        examples1:
          summary: 説明文、例えば「データがある場合」
          value:
            # ここ以降にレスポンスの例を記載します。
        examples2:
          summary: 説明文、例えば「データがない場合」
          value:
            # ここ以降にレスポンスの例を記載します。

同じHTTPステータスで、exampleだけではなく返却するオブジェクトを複数定義することもできるようです。

Swaggerで、とあるapiのレスポンスにおいて、「同じステータスコードを返すんだけれど、bodyの内容が違う場合がある」時、SwaggerのoneOfという書き方で対応できます。(swagger3.0以上だったはず)

【Swagger3.0】1つのステータスコードに対して複数のレスポンスを定義 (oneOf) - 196Log

YAMLファイルに保存する

ブラウザ上で書いたものをローカルにダウンロードしてYAMLファイルとして保存します。

f:id:ponsuke_tarou:20210121171039p:plain
[File] > [Save as YAML]から簡単に保存できる

f:id:ponsuke_tarou:20210122222954j:plain
新宿区の弁天湯