Swagger(OpenAPI)によるAPI設計
API設計の手順
API設計の手順を明確にすることで、どのような情報が必要か・定義すべきかを明確にし手戻りを防ぐ。
今回はSwagger(OpenAPI)によるAPI設計手法について実際のSwaggerに書くコードを示しながら0から解説していく。
(ChatGPTフル活用。)
API設計の粗さはシステムのバグやセキュリティの脆弱性に顕著に出る。
備忘録として残しているが、参考までに。
00.必要な資料の準備
- ERD(データベース設計資料)
- フローチャート
- 画面仕様書
- 機能設計書
01.リソース(データモデル)の洗い出し
例)ベーシックなECシステム
- ユーザー(Users)
- 商品(Products)
- カテゴリー(Categories)
- 注文(Order)
- 支払い情報(Payments)
02.リソースの関係性を定義する
洗い出したリソース感の関係性(has_one has_many dependency)などを定義する。
ここでERDを作成しながらどのようなスキーマになるかを策定する。
ERD参考:
※準備中
03.スキーマの作成
Swaggerの中でスキーマを作成する。
例)userのスキーマ
components:
schemas:
User:
type: object
properties:
userId:
type: string
name:
type: string
email:
type: string
password:
type: password
04.APIエンドポイントの設計
画面設計書のアクション(ユーザーインタラクション)を基にエンドポイントを作成する。
エンドポイントの命名には以下を気をつける必要がある。
- リソースは複数形を使用する("users" "orders")など
- 直感的で分かりやすい名称を使用する
- 単語の区切りはケバブケースを使用する(system-users)
- 特殊記号は使用しない
- ファイル拡張子はできるだけ使用しない
- URL中のパラメータ・ID部分はキャメルケースを使用する({orderId})
- レスポンスにリソースの総数を含める
など。
Swaggerへの落とし込み
エンドポイントを洗い出せたら(洗い出しながら)HTTPメソッド・パラメータと共にSwaggerへ落とし込んでいく。
paths:
/users/{userId}:
get:
summary: ユーザー情報を取得
parameters:
- name: userId
in: path
required: true
description: ユーザーID
schema:
type: string
05.レスポンスとエラーハンドリングの設計
エンドポイントを全て洗い出せたら、レスポンスを記載していく。
例
paths:
/users/{id}:
get:
summary: ユーザー情報を取得
parameters:
- name: id
in: path
required: true
description: ユーザーID
schema:
type: string
responses:
'200':
description: ユーザーの詳細情報を返します
content:
application/json:
schema:
$ref: '#/components/schemas/User'
examples: #examplesフィールドを活用した方が良い
user:
summary: ユーザーの例
value:
id: "1"
name: "山田 太郎"
email: "taro@example.com"
エラーハンドリング
ステータスコード別にエラー時のメッセージを定義しつつ、エラーハンドリングをする。
paths:
/users/{id}:
get:
summary: ユーザー情報を取得
parameters:
- name: id
in: path
required: true
description: ユーザーID
schema:
type: string
responses:
'200': #成功時
description: ユーザーの詳細情報を返します。
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400': #不正なリクエスト
description: 不正なリクエストです。例:パラメータの形式が不正です。
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalidRequest:
summary: 不正なリクエストの例
value:
code: 400
message: "不正なパラメータです。"
'404': #not found
description: 指定されたユーザーが見つかりません。
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
notFound:
summary: ユーザーが見つからない例
value:
code: 404
message: "指定されたユーザーが見つかりません。"
components:
schemas:
User:
type: object
properties:
id:
type: string
name:
type: string
email:
type: string
Error: #エラーレスポンス
type: object
properties:
code:
type: integer
message:
type: string
セキュリティと認証
APIセキュリティの必要性
利用するAPIが改善されていた場合、不正なデータが返ってくる場合や個人情報などのデータが傍受されてしまうリスクがある。
決済サービスや金融機関などのAPIを使用する際、認証情報が傍受されてしまうと金銭的被害が生まれる可能性も。
APIセキュリティの設計
設計段階でどのようなセキュリティ対策が必要か、どのようなセキュリティ技術を活用するか、どのように実装していくかを明確にする。
01.認証メカニズムの設計
認証方式の種類
- APIキー:APIの利用者に固有のキーを発行し、それをAPIリクエストに含めることで認証を行う
- ベアラートークン / JWT:トークンベースの認証方式。サーバーから発行されたトークンをリクエストヘッダーに含めることで認証を行う。
- OAuth2.0:第三者アプリケーションがユーザーの代わりにリソースにアクセスするための認証フレームワーク。
上記いずれかまたは複数を採用しセキュリティを強化する。
02.権限付与
APIそれぞれのリソースに対するアクセス権限を定義しアクセス制限をかける。
例)
- アクセス可能 / 不可
- 読み取り専用
- 読み書き可能
03.通信のセキュリティ
HTTPS(SSL化)を使用することでAPIとクライアント間の通信を保護できる。
04.脆弱性対策
SQLインジェクション・クロスサイトスクリプティング(XSS)などの脆弱性への対応・対策。
例)エスケープ処理など
Swaggerでの設計
Swaggerでは **"securitySchemes"**を用いることでAPIのセキュリティスキームを定義できる。
コード例(API key)
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
security:
- ApiKeyAuth: []
コード例(OAuth2.0)
components:
securitySchemes:
OAuth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://example.com/oauth/authorize
tokenUrl: https://example.com/oauth/token
scopes:
read: 読み取りアクセス権
write: 書き込みアクセス権
security:
- OAuth2:
- read
- write
Usesリソースに対する最終的なSwaggerの記載
openapi: 3.0.0
info:
title: Users API
version: 1.0.0
servers:
- url: https://example.com/api
paths:
/users:
get:
summary: ユーザーの一覧を取得
responses:
'200':
description: 成功
'400':
description: 不正なリクエスト
security:
- ApiKeyAuth: []
post:
summary: 新しいユーザーを作成
responses:
'200':
description: ユーザー作成成功
'400':
description: 不正なリクエスト
security:
- ApiKeyAuth: []
/users/{userId}:
get:
summary: 特定のユーザーの詳細情報を取得
parameters:
- name: userId
in: path
required: true
schema:
type: string
responses:
'200':
description: 成功
'404':
description: ユーザーが見つからない
security:
- ApiKeyAuth: []
put:
summary: 特定のユーザー情報を更新
parameters:
- name: userId
in: path
required: true
schema:
type: string
responses:
'200':
description: 更新成功
'400':
description: 不正なリクエスト
'404':
description: ユーザーが見つからない
security:
- ApiKeyAuth: []
delete:
summary: 特定のユーザーを削除
parameters:
- name: userId
in: path
required: true
schema:
type: string
responses:
'200':
description: 削除成功
'404':
description: ユーザーが見つからない
security:
- ApiKeyAuth: []
components:
schemas:
User:
type: object
properties:
id:
type: string
name:
type: string
email:
type: string
Error:
type: object
properties:
code:
type: integer
message:
type: string
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
Discussion