Ruby
Node.js
開発環境
swagger
モック

本記事では、SwaggerのAPI定義を行うSwagger YAMLの記法についてまとめてみました。

使い初めはとっつきにくいSwaggerですが、この記事がSwaggerを使う方の参考になれば幸いです。


Swagger Editorの紹介

Swagger YAMLを書く際には、Swagger Editorがとても便利です。

画面左側がエディター、右側がSwagger UIとなっておりリアルタイムで記法のチェックや定義書を確認できます。

Swaggerを書くエディタはいろいろありますが、気軽に記法を試す際にはSwagger Editorがとても便利です。

ぜひこれから紹介する記法を試す際にも、ぜひ使ってみてください。


初級編


基本の記述

初めにSwagger YAMLを記述するにあたり必須であるswagger, info, pathsについて説明します。

上記の基本的な構成で記述したシンプルなSwagger YAMLがこちらです。

swagger: "2.0"

info:
description: "これはペットストアに関するAPIです。"
version: "1.0.0"
title: "Petstore API"
termsOfService: "http://swagger.io/terms/"
contact:
email: "apiteam@swagger.io"
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
paths:
/pet/{petId}:
get:
summary: "ペット情報API"
description: "指定されたpetIdの情報を返します"
parameters:
- name: "petId"
in: "path"
description: "取得したいペットのID"
required: true
type: "integer"
format: "int64"
responses:
200:
description: "成功時のレスポンス"
schema:
type: "object"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
example: "doggie"

以降、このサンプルを基に記法を説明します。

実際に上記のSwagger YAMLをSwagger Editorに入力すると、画面右側にAPI定義書が下記のように作成されます。

1.png

それでは、 swagger, info, pathsそれぞれのオブジェクトの書き方について説明します。

2.png


swagger

swaggerには、Swaggerのバージョンを記述します。

変更する理由がない限りはここの値は 2.0にしておきます。


info

タイトル・説明・バージョンなど、APIについての情報を記載します。

infoには、以下の情報を記述できます。

フィールド名

説明
必須

version
string
APIのバージョン
必須

title
string
ドキュメントのタイトル。一番上に表示される。
必須

description
string
ドキュメントについての説明

termsOfService
string
利用規約

contact
contact object
APIについての問い合わせ先

license
license object
APIのライセンス


paths

APIのエントリポイントを記述します。

サンプルでは下記の部分にあたります。

parameters.png

ここで定義する情報をもとにエントリポイントが作成されるため、pathsはとても重要なパートとなります。

pathsには、下記のような階層形式で情報を記載します。


  • パスのURL(/pet/{PetId})


    • HTTPメソッド(get, postなど)


      • エントリポイントのリクエストとレスポンスに関する記述





request_response.png


パスのURL

実際に定義したいエントリポイントのパスを記述します。

サンプルでいうところの /pet/{petId}です。


HTTPメソッド(get, post, put, delete等)

パスの下には、パスのHTTPメソッドを記述します。

下記のように複数記述することもできます。

  /pet/{petId}:

get:
summary: "ペット情報API"
description: "指定されたpetIdの情報を返します"
parameters: 省略
responses: 省略 
delete:
summary: "ペット情報API"
description: "指定されたpetIdを削除します"
parameters: 省略
responses: 省略


エントリポイントのリクエストとレスポンスに関する記述

HTTPメソッドの下層には、エントリポイントがどのようなリクエストを受け取り、どのようなレスポンスを返すかを記述します。

サンプルでは、この部分にあたります。

response.png

設定できるフィールドは以下になります。

フィールド名

説明
必須

responses
response object
返ってくるレスポンス
必須

parameters
parameter object
リクエストのパラメーター

tags
array
swaggerオブジェクトで定義するどのtagに紐付けたいかを記述

summary
string
エントリポイントの概要(120文字以内)

description
string
エントリポイントの説明

consumes/produces
array
MIME Type

schemes
array
APIの通信プロトコル。必ずhttp, https, ws, wssの4種類のどれかを記述する。

security
security requirement object
適用するセキュリティ

externalDocs
external docs document
外部リンク

deprecated
boolean
Deprecatedかどうかをtrueかfalseで記述。デフォルトはfalse。

もっとも重要なparametersとresponsesについて補足説明します。


parameters

リクエストの際に渡すパラメーターを記述します。

サンプルでは下記の部分にあたります。

parameter.png

記述するフィールドは以下です。

フィールド名

説明
必須

name
string
パラメーター名
必須

in
string
パラメータの場所。query, header, path, formData, bodyの5種類のどれかを記述してください
必須

description
string
パラメータの説明

required
boolean
必須パラメーターかどうかをtrueかfalseで記述

schema
schema object
bodyのパラメーターをスキーマオブジェクトとして記述。スキーマオブジェクトについては後述。inがbodyである場合に使用。
inがbodyである場合、必須

type
string
パラメーターのタイプ。
必ずstring, number, integer, boolean, array, fileの中から選ぶ。inがbody以外である場合に使用。
inがbody以外である場合、必須

format
string
パラメーターの型。こちらから選ぶ。inがbody以外である場合に使用。

typeとformatの指定は、こちらが参考になります。

パラメーターが記述されると定義書ではこのように表示されます。

parameter_example.png


responses

返ってくるレスポンスを記述します。

サンプルでは下記の部分にあたります。

response_example.png

返したいHTTPステータスコードごとに、定義を行います。

定義できる設定は下記です。

フィールド名

説明
必須

description
string
レスポンスの説明
必須

schema
schema object
レスポンスのbody。スキーマオブジェクトで記述する。スキーマオブジェクトについては後述。

headers
headers object
レスポンスヘッダーを記述

example
example object
レスポンス例。レスポンスの値を自分で定義したいときに用いる。

レスポンスを設定すると定義書が下記のように生成されます。

response_definition.png


スキーマオブジェクトについて

parameters, responsesを記述する際に、schemaを記述することができます。

このschemaにはスキーマオブジェクトを記述します。

スキーマオブジェクトは、bodyに用いるデータのタイプを定義することができるオブジェクトです。

主に配列かJSONオブジェクトを表現するときに使います。


JSONオブジェクト

schema:

type: object

と指定すると、JSONオブジェクトを返すことができます。

例えば、APIのレスポンスを下記のように返したいとします。

{

"id": 1,
"name": "doggie"
}

この場合はschemaをこのように書きます。

schema:

type: object
properties:
id:
type: "integer"
format: "int64"
example: 1
name:
type: "string"
example: "doggie"

type: objectを指定した場合は、propertiesを設定します。

propertiesでは、カラムの情報を記述します。

propertiesには基本的に下記3つが記述されていれば動作します。

フィールド名

説明

type
string
パラメーターのタイプ。必ずstring, number, integer, boolean, array, fileの中から選ぶ。

format
string
パラメーターの型。

example
typeで選んだ型
レスポンスで返したい文言

typeとformatの指定は、こちらが参考になります。


配列

schema:

type: array

と指定すると、配列を定義することができます。

例えば、APIのレスポンスを下記のように返したいとします。

[

{
"id": 1,
"name": "doggie"
}
]

この場合はschemaをこのように書きます。

schema:

type: array
items:
type: "object"
properties:
id:
type: "integer"
format: "int64"
example: 1
name:
type: "string"
example: "doggie"

type: arrayを指定した場合は、itemsを設定します。

itemsには、配列の中のオブジェクトを記述します。

配列の中に、JSONを定義したい場合は、type:objectを指定します。

schema:

type: array
items:
type: "object"
properties:
id:
type: "integer"
format: "int64"
example: 1
name:
type: "string"
example: "doggie"

また、配列の中に文字列を定義したい場合は、 type: stringを記述します。

schema:

type: array
items:
type: "string"


中級編


Swaggerを構成するオブジェクト

Swaggerは初級編で紹介したswagger, info, pathsも合わせ計15種類のオブジェクトから成り立っています。

多く感じられますが、すべてが必須というわけでなく、必須であるswagger, info, pathsが記載されていれば動きます。

必須以外のものは定義書に記載したいものがあれば記述します。

フィールド名

説明
必須

swagger
string
swaggerのバージョン。特に指定がなければ、デフォルトの2.0のままで大丈夫です。
必須

info
info object
タイトル・説明・バージョンなど、APIについての情報を記載します。
必須

paths
paths object
提供するAPIのパスを書いていきます。Swagger定義の要です。
必須

host
string
API通信を行うサーバーのホスト。無記載であればドキュメントが動いているサーバーのホストとなります。

basePath
string
ホストに続くパス。スラッシュ(/)から始まる必要があります。無記載の場合、ホストの直下になります。
hostをexample.com
basePathを/v2とした場合、APIのパスはhttp://example.com/v2/〜となります。

schemes
array
APIの通信プロトコル。必ずhttp, https, ws, wssの4種類のどれかを記載してください。無記載の場合、Swaggerの定義書がアクセスしているスキームになります。

produces
array
APIが提供できるMIME Typeの指定。選択肢はこちら

consumes
array
APIが使用するMIME Typeの指定。選択肢はこちら

definitions
definitions object
レスポンスやパラメータに使用するデータ定義を記載します。

parameters
parameters definitions object
パラメーターを定義します。pathsの下に直接パラメーターを書くこともできますが、複数回同じパラメーターを使う場合に便利です。

responses
responses definitions object
レスポンスを定義します。pathsの下に直接レスポンスを書くこともできますが、複数回同じレスポンスを使う場合に便利です。

securityDefinitions
security definitions object
セキュリティに関する定義を行えます。Oath認証についてもこちらで定義します。

security
security requirement object
securityDefinitionsにて定義したセキュリティの中で何を適用するかを指定します。

tags
[tag object]
タグの名前と説明を定義します。定義したタグをpathに紐付けることで、タグごとにpathがまとまりドキュメントが見やすくなります。

externalDocs
external documentation object
外部リンクを定義します。ドキュメントに貼りたいリンクがある場合、記載することでリンクが作成されます。

それぞれのオブジェクトの記述は、Swagger Editorにデフォルトで入っているPet store APIがわかりやすく参考になります。


definitionsを使う

同じスキーマオブジェクトを複数回使用したい場合、definitionsを使用しテンプレートとして定義することができます。

definitions.png

definitionsを使う際のポイントは、下記のようになります。


  • テンプレート化したいスキーマオブジェクトを、definitionsに定義をする

  • 呼び出したい箇所に、$refを使用して、definitionsのオブジェクトを呼び出す

サンプルをdefinitionsを用いて書き換えると以下のようになります。

paths:

/pet/{petId}:
get:
省略
responses:
200:
description: "成功時のレスポンス"
schema:
$ref: "#/definitions/Pet" # definitionsで定義されたスキーマオブジェクトを呼び出す
definitions:
Pet: # テンプレート名
type: "object"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
example: "doggie"

definitionsは本当に便利です。

definitionsにレスポンスのスキーマを全て定義しpathsではそれらを呼び出すだけというような記述にすると、Swagger YAMLが見やすくなるのでオススメです。


definitionsを複数呼び出す

definitionsにて定義したスキーマオブジェクトを複数呼び出すことも可能です。

下記のように、Storeの情報をdefinitionsで定義して呼び出してみます。

paths:

/pet/{petId}:
get:
省略
responses:
200:
description: "成功時のレスポンス"
schema:
type: "object"
properties:
pet:
$ref: "#/definitions/Pet"
store:
$ref: "#/definitions/Store"
definitions:
Pet:
type: "object"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
example: "doggie"
Store:
type: "object"
properties:
id:
type: "integer"
format: "int64"
example: 1
store_name:
type: "string"
example: "ABC PET STORE"

レスポンスはこのようになります。

{

"pet": {
"id": 0,
"name": "doggie"
},
"store": {
"id": 1,
"store_name": "ABC PET STORE"
}
}

schema:

type: "object"

上記のように記述し、JSONオブジェクトのそれぞれのキーにdefinitionsで定義したスキーマオブジェクトを呼び出します。


上級編


definitionsを入れ子にする

中級編では、レスポンスにdefinitionsで定義したスキーマオブジェクトを呼び出しました。

definitionsはスキーマオブジェクトを定義し、呼び出すことができるのでschemaが使えるところではどこでも呼び出すことができます。

例えば、definitionsの中でスキーマオブジェクトを呼び出すことも可能です。

paths:

/pet/{petId}:
get:
省略
responses:
200:
description: "成功時のレスポンス"
schema:
$ref: "#/definitions/Pet"
definitions:
Pet:
type: "object"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
example: "doggie"
stores:
type: "array"
items:
$ref: "#/definitions/Store" # Storeを呼び出す
Store:
type: "object"
properties:
id:
type: "integer"
format: "int64"
example: 1
store_name:
type: "string"
example: "ABC PET STORE"

上記のようにレスポンスを定義した場合、レスポンスはこのように生成されます。

{

"id": 0,
"name": "doggie",
"stores": [
{
"id": 1,
"store_name": "ABC PET STORE"
}
]
}

storesの配列の中で、itemsの1つとしてStoreオブジェクトを呼び出しています。


Swagger YAMLを書く上で気をつけたい点

ここからは、実際に私がSwagger YAMLを書く上でうまくいかなかったりつまづいた点を共有の意味を込めてご紹介します。


レスポンスの配列に複数データを入れたい

通常レスポンスに配列を定義する際は、このように記述します。

schema:

type: array
items:
type: "object"
properties:
id:
type: "integer"
format: "int64"
example: 1
name:
type: "string"
example: "doggie"

この記述で返ってくるレスポンスは[ { id: 1, name: "doggie" } ]と要素が1つしか返ってきません。

2つ以上の配列要素を追加したい場合は、オブジェクト自体のexampleを記述します。

paths:

/pet/{petId}:
get:
省略
responses:
200:
description: "成功時のレスポンス"
schema:
type: "object"
properties:
pet:
$ref: "#/definitions/Pet"

definitions:
Pet:
type: "array"
items:
example:
- id: 1
name: "doggie"
- id: 2
name: "pochi"


formatを指定しても、デフォルトで値が入らない

Swaggerのドキュメントには、スキーマオブジェクトのformatにemailやuuidを指定するとexampleを設定しなくても値が入るという記述があります。

実際、Swagger Editorでは下記のようにデフォルトで値が入ります。

format.png

しかし、Swagger Codegenを使ってモックアプリケーションを生成する場合には、formatを指定してもデフォルトで値が入りません。

formatのデフォルト値を使用する際は、ご自分の環境でデフォルト値が入るかどうかを確認してから使う方が良いと思います。


Amazon API Gatewayではexampleが使えない

Swaggerを用いてAPIを生成するサービスの1つに、Amazon API Gatewayがあります。

API Gatewayは、Swagger YAMLをインポートすることで簡単にAPIを作成することができます。

API Gatewayを用いてAPIを作成する方法については、下記の2つが参考になるのでぜひ読んでみてください。

例から API Gateway API を作成する - Amazon API Gateway

開発効率を上げる!Swaggerで作るWEB APIモック - VASILY DEVELOPERS BLOG

API GatewayにSwagger YAMLをインポートしてモックアプリケーションを作成する場合は、exampleが使えません。

exampleが記述されているSwagger YAMLをAPI GatewayでロードするとInvalid model schema specifiedというエラーが返ってきます。

API Gatewayでレスポンス例を記述したい時は、下記のように総合レスポンスの設定時に記述しましょう。

aws.png


まとめ

以上、基本的なSwagger YAMLの書き方についてご紹介しました!

Swaggerは高機能であるゆえに、最初はとてもとっつきにくく感じてしまいます。

しかし一度覚えてしまえば、Swaggerは開発効率を上げることができるとても便利なフレームワークです。

この記事では紹介しきれなかった機能も多くあるので、公式ドキュメントを参考にしてみてください。


参考