内容
OpenAPIとSwaggerについての備忘録 兼 チートシート。
用語
OpenAPI, OpenAPI Specification, Swaggerについて。
OpenAPI | フォーマットのこと。 このフォーマットを使うと、機械可読可能なREST API設計が作成できる。 |
---|---|
OpenAPI Specification | ルールのこと。 OpenAPIを記述するための書式ルール。 |
Swagger | OpenAPIでAPI設計を作成する際に使うツール。 |
Swaggerは以下3種類が含まれている。
Swagger Editor | OpenAPIを記述するエディター。 |
---|---|
Swagger UI | Swagger Editorで作成したOpenAPIをドキュメントとして表示できる。 |
Swagger Codegen | Swagger Editorで作成したOpenAPIをコードとして出力できる。 |
備考
GithubでOpenAPIのマニュアルが確認できる。
https://github.com/OAI/OpenAPI-Specification/tree/master/versions
OpenAPI-Specification/versions/確認したいVer.
Swagger Editorの使用方法
主に以下4通りから。
- Dockerイメージ
- Github
- Web
- IDEのプラグイン
記述フォーマット
JSONかYAMLだが、YAMLが一般的。
データ型
以下が主なデータ型。
これらは、Schemaオブジェクトに定義する。
integer, number, stringに関しては、詳細なformatを指定できる。
- integer: 整数
- int32
- int64
- number: 浮動小数
- float
- double
- string: 文字列
- byte
- binary
- date
- date-time
- hostname
- uri
- boolean: 真偽
- array: 配列
- object: オブジェクト
記述例
openapi: "3.0.3"
info:
title: "Sample"
version: "1.0"
paths: {}
components:
schemas:
Int:
type: integer
format: int64
Date:
type: string
format: date
ルートオブジェクト
主なルートオブジェクトは、以下7種類。
openapi: 使用するopenapiのバージョン。 ※必須項目
info: APIのメタデータ(タイトルとか仕様書のバージョン)。 ※必須項目
servers: APIが動くサーバー情報。配列で定義。
tags: API分類用のタグ。配列で定義。
paths: APIのパスや操作 ※必須項目。オブジェクトで定義。
security: APIのセキュリティ要件について。配列で定義。
components: データ型の例のように、OpenAPIの中で何度も使うオブジェクトを定義する。オブジェクトで定義。
info
APIのメタデータを定義するオブジェクト。
openapi: "3.0.3"
info:
# APIのタイトル
title: "Sample API"
# 仕様書のバージョン
version: "1.0"
# APIの詳細説明。mark downが使える。
description: |
# 概要
- xxxからのリクエストをoooでレスポンスする。
paths: {}
servers
接続先のURLや環境情報を定義するオブジェクト。
openapi: "3.0.3"
info:
title: "Sample API"
version: "1.0"
servers:
# 接続先URL
- url: "http://localhost:{port}"
# 接続先URLについての説明
description: "Local"
# 接続先URLで指定しているテンプレート変数の内容についての定義
variables:
# 変数名
port:
# 値
enum: ["3000", "8080"]
# default値は必須
default: "8080"
- url: "https://dev.sample.com"
description: "Dev"
- url: "https://stg.sample.com"
description: "Staging"
- url: "https://sample.com"
description: "Production"
paths: {}
paths
APIの具体的なエンドポイントや操作内容を定義するオブジェクト。
以下のパートに分かれて定義する。
paths:
# メソッド
get:
# メタデータ
summary:
# リクエストパラメータ
parameters:
# リクエストボディ
requestBody:
# レスポンス
responses:
# セキュリティ
security:
summary
paths:
# パス
"/sample/versions/{version}/sample_api":
get:
# 操作の概要説明
summary: "get sample parameters"
# 操作の詳細説明
description: "description: get sample parameters"
# タグ
tags: ["Sample"]
# APIがactiveかどうか
deprecated: false
deprecated: true にした場合は、swagger UIの方はグレーアウトされる。
parameters
paths:
"/sample/{id}/samples":
post:
summary: "sample"
description: "description: sample"
tags: ["Sample"]
deprecated: false
# リクエストパラメータ
parameters:
# パラメータ名
- name: id
# パラメータの定義場所(query, header, path, cookie)
in: path
# パラメータの説明
description: "id in path"
# パラメータが必須か(デフォルトはfalse)
required: true
# パラメータの型
schema: { type: string }
# サンプルパラメータ
example: "example"
- name: token
in: cookie
description: "one time token"
schema: { type: string }
example: "token"
responses:
"201":
description: "Success"
【備考】HTTPメソッドとステータスコードについて
- GET
ステータスコード | 成功 / 失敗 | 概要 | 内容 |
---|---|---|---|
200 | 成功 | OK | 正常 |
304 | 成功 | Not Modified | キャッシュ利用時 |
400 | 失敗 | Bad Request | クライアント側のリクエスト内容の不備 |
401 | 失敗 | Unauthorized | 認証エラー:リクエストしてきたユーザーが未認証 |
403 | 失敗 | Forbidden | 認可エラー:認証済みだが、アクセス権限がない |
404 | 失敗 | Not Found | リクエストしたリソースが存在しない |
429 | 失敗 | Too Many Requests | レートリミットの制限を超えた |
500 | 失敗 | Internal Server Error | サーバー側で障害が発生した場合 |
503 | 失敗 | Service Unavailable | 高負荷の状態で応答ができない |
- POST
ステータスコード | 成功 / 失敗 | 概要 | 内容 |
---|---|---|---|
200 | 成功 | OK | 正常 |
201 | 成功 | Created | レスポンスボディが空で、Locationレスポンスヘッダーにリダイレクト先が含まれる場合 |
202 | 成功 | Accepted | 非同期処理の受付完了 |
400 | 失敗 | Bad Request | クライアント側のリクエスト内容の不備 |
401 | 失敗 | Unauthorized | 認証エラー:リクエストしてきたユーザーが未認証 |
403 | 失敗 | Forbidden | 認可エラー:認証済みだが、アクセス権限がない |
409 | 失敗 | Conflict | 複数のアクセスポイントから同じデータを登録しようとして衝突が起きる |
429 | 失敗 | Too Many Requests | レートリミットの制限を超えた |
500 | 失敗 | Internal Server Error | サーバー側で障害が発生した場合 |
503 | 失敗 | Service Unavailable | 高負荷の状態で応答ができない |
requestBody
paths:
"/sample/{id}/samples":
post:
summary: "sample"
parameters:
- name: id
in: path
required: true
schema: { type: string }
requestBody:
# リクエストボディの説明
description: "body sample"
# リクエストボディが必須か
required: true
# リクエストボディの内容
content:
# メディアタイプ
application/json:
# 中身のデータ型
schema:
type: object
properties:
num: { type: integer, example: 10 }
word: { type: string, example: "test" }
responses:
"201":
description: "success"
schemaの定義部分は表示切り替えが可能
responses
paths:
"/sample/{id}/samples":
post:
summary: "sample"
parameters:
- name: id
in: path
required: true
schema: { type: string }
requestBody:
description: "sample"
required: true
content:
application/json:
schema:
type: object
properties:
num: { type: integer }
word: { type: string }
responses:
# ステータスコードごとに定義する
# yamlとjsonとの互換性のため、””で囲う
# 4XXや5XXでまとめることも可能
"201":
# レスポンスの説明
description: "success"
# レスポンスヘッダー
headers:
location:
description: "location url"
schema: { type: string, format: url }
"400":
description: "client error"
# レスポンスボディ
content:
application/json:
schema:
type: object
properties:
code: { type: string }
type: { type: string }
message: { type: string }
errors:
type: array
items:
type: object
properties:
field: { type: string }
code: { type: string }
tags
paths配下に設定できるtagsを定義することで、タグ付けしてまとめることができる。
# tagsでタグの定義をして、それをpaths配下で利用する
tags:
- name: sampleTag
description: "sample tag"
paths:
"/sample/{id}/samples":
get:
summary: "get sample"
# タグは複数付与可能
tags: ["sampleTag"]
parameters:
- name: id
in: path
required: true
schema: {type: string}
responses:
"200":
description: "success"
post:
summary: "post sample"
tags: ["sampleTag"]
parameters:
- name: id
in: path
required: true
schema: {type: string}
responses:
"201":
description: "success"
【備考】共通化
同じpaths内で、同じparametersを2つのメソッド内で使っているので、
paths:
"/sample/{id}/samples":
get:
summary: "get sample"
tags: ["sampleTag"]
# postのparametersと同じ内容
parameters:
- name: id
in: path
required: true
schema: { type: string }
responses:
"200":
description: "success"
post:
summary: "post sample"
tags: ["sampleTag"]
# getのparametersと同じ内容
parameters:
- name: id
in: path
required: true
schema: { type: string }
responses:
"201":
description: "success"
記述をひとまとめにできる。
paths:
"/sample/{id}/samples":
# メソッドと同じ階層にもってこれる
parameters:
- name: id
in: path
required: true
schema: { type: string }
get:
summary: "get sample"
tags: ["sampleTag"]
responses:
"200":
description: "success"
post:
summary: "post sample"
tags: ["sampleTag"]
responses:
"201":
description: "success"
security
OpenAPIで定義可能な認証・認可のタイプを以下にまとめる。
type | scheme | 説明 |
---|---|---|
http | basic bearer |
basic認証 JWTを使用した認可方式 |
apiKey | header cookie |
APIキーを使用した認可方式 ログインセッション |
OAuth | - | 本人認証 |
OpenID Connect | - | 本人認証 + アクセス制御 |
定義方法は、以下2通り。
- pathsに個別に定義
paths:
"/sample/{id}/samples":
get:
summary: "get sample"
tags: ["sampleTag"]
parameters:
- name: id
in: path
required: true
schema: {type: string}
responses:
"200":
description: "success"
# components配下で定義したsecuritySchemesを指定
security:
# scopeがないもの(basic認証やJWTなど)は空の配列を定義
# scopeがあるもの(OAuthやOpenID Connect)はスコープ名を定義
- sample_auth: []
components:
securitySchemes:
sample_auth:
type: http
description: "JWTを使用した認可方式"
scheme: bearer
bearerFormat: JWT
- ルートオブジェクトとして定義し全体に適用させ、paths内で個別に解除
paths:
"/sample/{id}/samples":
get:
summary: "get sample"
tags: ["sampleTag"]
parameters:
- name: id
in: path
required: true
schema: {type: string}
responses:
"200":
description: "success"
# 解除したいAPIに対して空配列を定義する
security: []
# ルートオブジェクトとして定義
security:
- sample_auth: []
components:
securitySchemes:
sample_auth:
type: http
description: "JWTを使用した認可方式"
scheme: bearer
bearerFormat: JWT
components
複数箇所で使用する記述をcomponents配下にまとめて、使用箇所で参照することができる。
componentsとして使用できる要素は以下6種類。
- paths
- schemas
- parameters
- requestBodies
- responses
- headers
- components
- securitySchemes
記述例
paths:
"/sample/{id}/samples":
get:
summary: "get sample"
tags: ["sampleTag"]
parameters:
- name: id
in: path
required: true
schema: {type: string}
responses:
"200":
description: "success"
content:
application/json:
schema:
# $refで参照できる
$ref: "#/components/schemas/sample"
components:
securitySchemes:
sample:
type: object
properties:
id: {type: integer}
description: {type: string}