>100 Views
November 28, 25
スライド概要
Mobile Tech Talk Osaka by TRAILBLAZER & TRUSTDOCK で発表した資料。
https://trustdock.connpass.com/event/374026/
今更 Open API Document の 分割に向きあう experopero
こんにちは
北村 涼||experopero|| funnelbit • エンジニアです • 奈良に住んでいます • サーバサイドとフロントエン ド、iOS、Android など色々や っていましたが最近は Android ばかりやっています • X: https://x.com/experopero • Blog: https:// funnelbit.hatenablog.com/
GraphQL
最高
NOW
REST
最近の事情を知らない
自分が REST やってた 時代
ドキュメントはコード
サーバサイドもフロントも 同時に同じ人が作るから
特に問題なし
フロントも動的型付け
コードレビューで防ぐと いう世界観
しかし今は
多数の配信先が静的型付 け
Typescript/Kotlin/Swift etc…
どうするのかというと
Open API Document
openapi.yaml
Or
openapi.json
適当に作ると
巨大化していく
100行
500行
1000行
9000行
「Openapi.yaml の記載、レビュー お願いします!」 9200行
🤯
勘弁してくれ
分割しようよ
どう分割すれば?
適当に調べた
みんな好き勝手やってる 気がする
とりあえずやってみる
openapi: 3.0.4 info: title: Sample API description: これはサンプルAPIの説明です version: 1.0.0 contact: name: API Support email: [email protected] servers: - url: https://api.example.com/v1 description: 本番環境 - url: https://staging-api.example.com/v1 description: ステージング環境 paths: /users: get: openapi.yaml
openapi: 3.0.4 info: title: Sample API description: これはサンプルAPIの説明です version: 1.0.0 contact: name: API Support email: [email protected] servers: - url: https://api.example.com/v1 description: 本番環境 - url: https://staging-api.example.com/v1 description: ステージング環境 paths: /users: get: openapi.yaml
$ref
fi $ref: "reference to de nition"
fi https://swagger.io/docs/ speci cation/v3̲0/using-ref/
paths: /users: get: … responses: '200': … $ref: '#/components/schemas/User' components: schemas: User: type: object openapi.yaml
paths: /users: get: … responses: '200': … $ref: '#/components/schemas/User' components: schemas: User: type: object openapi.yaml
paths: /users: get: … responses: '200': … $ref: ‘schemas.yaml#/components/schemas/User'
よしわかった!!
エンドポイントの paths は 肥大化するから分割するぞ!!
openapi: 3.0.4 … $ref: paths.yaml
❌
openapi: 3.0.4 … paths: $ref: paths.yaml
❌
openapi: 3.0.4 … paths: /users: $ref: 'paths/users.yaml'
⭕
fi Open API Speci cation をちゃんと読め
fi https://swagger.io/ speci cation/
paths: Map[{String}, {Path Item Object}]
Path Item Object
$ref, summary, description, get, put, post, delete, options, head, patch, trace, servers, parameters
此れに沿う
Root は paths を持つことができる。 Paths は Path Item を持つことができる。 Path Item の内部は $ref できる。 openapi: 3.0.4 … paths: /users: $ref: 'paths/users.yaml'
実は分割した Root 以外のyaml は 無秩序
分割後ファイルはただの yaml
get: … $ref: '#/components/schemas/User' components: schemas: User: type: object required: - id - name - email properties: id: type: integer format: int64 description: ユーザーID example: 1 Paths/users.yaml
get: … $ref: '#/components/schemas/User' components: schemas: User: type: object required: - id - name - email properties: id: type: integer format: int64 description: ユーザーID example: 1 Paths/users.yaml
$ref, summary, description, get, put, post, delete, options, head, patch, trace, servers, parameters
Components: 書けるはずがないが
書ける
VSCode で openapi の 拡張入れても
Openapi のファイルじ ゃないとみなすから。
じゃあ好き勝手書けるんですね! 👌 最強の分割を見せてやるぞ!
しかし
重要なポイント
yaml は合体せねばなら ない
Open API Generator Kotlin
分割した Yamlを 読める
Swift Open API Generator
分割した Yaml 読めない
「yaml、S3 におきたい んすよね~」
結合したくなる
分割したいけど 分割したら 困る!?
ならば書くのは分割 成果物は合体後だ
Redocly
https://redocly.com/docs/ cli/commands/bundle
これで合体可能
fi Open API Speci cation に沿った分割なら
難なく結合できる
fi Open API Speci cation に 沿っていない分割方法だと
結合後に 構文エラーになる
get: … $ref: '#/components/schemas/User' components: schemas: User: type: object required: - id - name - email properties: id: type: integer format: int64 description: ユーザーID example: 1 paths/users.yaml
schema は Root にしか存在しないから。
ただし
Open API Generator な ら無茶しても結合できる
Open API Generator な ら無茶しても結合できる
$ openapi-generator-cli generate -g openapi-yaml -i a.yaml -o b.yaml
get: … $ref: '#/components/schemas/User' components: schemas: User: type: object required: - id - name - email properties: id: type: integer format: int64 description: ユーザーID example: 1 Paths/users.yaml
あまりお勧めしない
1. いくらでも好きな書き 方ができてしまう
どこに何を書いていいか 逆に難しい
俺の考えた最強の書き方 を
発明せねばならない
2. Open API Generator しか結合不可能
Open API Generator が 転けたら終了
先日も奇妙なエラー
type: object … properties: … favorites: allOf: - $ref: '#/components/schemas/Favorites' nullable: true followers: allOf: - $ref: '#/components/schemas/Followers' nullable: true Schemas/users.yaml
type: object … properties: … favorites: allOf: - $ref: '#/components/schemas/Favorites' nullable: true followers: allOf: - $ref: '#/components/schemas/Followers' nullable: true Schemas/users.yaml
結合後に
片方の nullable: true 消失
原因
不明 (まだよく調べていない)
ただし
一つの学び
やんちゃなことはしない 方がいい
Redocly
ただ結合するだけ
シンプル
結果も予測しやすい
Open api generator
よしなにマージしようと する
結果が読みにくい
シンプルに越したことは ない
シンプル第1を考えると
- openapi.yaml - paths/ -- users.yaml - components/ -- responses/ -- requestBodies/ -- schemas/ --- Users.yaml
- openapi.yaml - paths/ -- users.yaml - components/ -- responses/ -- requestBodies/ -- schemas/ --- Users.yaml
エントリポイント
ベタがき禁止
全部 $ref を並べる エントリポイントとして。
openapi: 3.0.4 … paths: /users: $ref: 'paths/users.yaml' components: schemas: User: $ref: 'components/schemas/User.yaml' openapi.yaml
- openapi.yaml - paths/ -- users.yaml - components/ -- responses/ -- requestBodies/ -- schemas/ --- Users.yaml
エンドポイント書くとこ ろ
Response する内容を 可能な限り ベタがきしない
get: summary: ユーザー一覧を取得 description: すべてのユーザーのリストを取得します operationId: getUsers tags: - Users responses: '200': description: 成功 content: application/json: schema: type: object properties: users: type: array items: $ref: '../api.yaml#/components/schemas/User'
- openapi.yaml - paths/ -- users.yaml - components/ -- responses/ -- requestBodies/ -- schemas/ --- Users.yaml
共通化したい 構造体を 書くところ
type: object required: - id - name - email properties: id: type: integer format: int64 description: ユーザーID example: 1 name: type: string description: ユーザー名 example: 山田太郎 email: type: string format: email description: メールアドレス example: [email protected] createdAt: type: string format: date-time description: 作成日時 example: '2024-01-01T00:00:00Z' Components/schemas/ User.yaml
分け終わったら
Redocly bundle
一つの openapi.yaml へ
こんなところですかね
実は他にも色々
エンドポイントのバージョ ン増えたらどう分けるの
openapi.yaml を書いたわけなので、 Redocly で bundle した後の yaml 名どうすんの?
Path パラメータとったエンドポイントの yaml 名どうすんの? /users/{id}
Openapi 3.0.4 って古くな い?時代は 3.1.x でしょ?
興味がある人は後で。
まとめ
Redcoly で結合すること
fi 分割後ファイルも Open API Speci cation に 沿ってあげること
独自色はできる限り出さ ない
fi ディレクトリの分割も Open API Speci cation の記載っぽくする
おしまい