---
title: 実装と乖離させないスキーマ駆動開発フロー / OpenAPI Laravel編
tags:  #スキーマ駆動開発 #laravel #openapi  
author: [katzumi](https://www.docswell.com/user/katzumi)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/47MV45Y67W.jpg?width=480
description: 実装と乖離させないスキーマ駆動開発フロー / OpenAPI Laravel編 by katzumi
published: June 18, 23
canonical: https://www.docswell.com/s/katzumi/ZJLX7X-schema-driven-development-flow
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/47MV45Y67W.jpg)

実装と乖離させないスキーマ駆
動開発フロー / OpenAPI Laravel
編
（非公式）PHP Conference Fukuoka After Hack!!
June 25, 2023.
v0.0.21
Press Space for next page


# Page. 2

![Page Image](https://bcdn.docswell.com/page/P7R2W39NJ9.jpg)

自己紹介
katzumiと申します
以下のアカウントで活動しています
katzchum
k2tzumi katzumi


# Page. 3

![Page Image](https://bcdn.docswell.com/page/PJXDP4Q8EX.jpg)

スキーマ駆動開発のフローってどうやっていますか？
本LTではクライアント（フロントエンド）の実装はさておいて、主にAPI（バックエンド）の実装についてお
話します。


# Page. 4

![Page Image](https://bcdn.docswell.com/page/3JKXDZ9LED.jpg)

スキーマ駆動開発のフローってどうやっていますか？
本LTではクライアント（フロントエンド）の実装はさておいて、主にAPI（バックエンド）の実装についてお
話します。
ドキュメント（スキーマ定義の仕様書）が先？


# Page. 5

![Page Image](https://bcdn.docswell.com/page/LE35RDW6J5.jpg)

スキーマ駆動開発のフローってどうやっていますか？
本LTではクライアント（フロントエンド）の実装はさておいて、主にAPI（バックエンド）の実装についてお
話します。
ドキュメント（スキーマ定義の仕様書）が先？
APIの実装（コード）が先？


# Page. 6

![Page Image](https://bcdn.docswell.com/page/8EDDYPKMEG.jpg)

問題点
スキーマ定義（ドキュメント）と実際の実装（コード）が乖離してしまう


# Page. 7

![Page Image](https://bcdn.docswell.com/page/V7PX6NKQE8.jpg)

なぜ乖離が発生するのか？
ドキュメントが先の場合（コードが先であっても。。）


# Page. 8

![Page Image](https://bcdn.docswell.com/page/2JVL3KVP7Q.jpg)

なぜ乖離が発生するのか？
ドキュメントが先の場合（コードが先であっても。。）
Open API Spec
コード生成
Stub
コード
実装
実際のコード


# Page. 9

![Page Image](https://bcdn.docswell.com/page/5EGX3QLQJL.jpg)

なぜ乖離が発生するのか？
ドキュメントが先の場合（コードが先であっても。。）
*
変更
コード生成
Open API Spec
Stub
コード
❌ 変更済みのStubを反映することはできない
実装
実際のコード


# Page. 10

![Page Image](https://bcdn.docswell.com/page/4JQ85KYW7P.jpg)

なぜ乖離が発生するのか？
ドキュメントが先の場合（コードが先であっても。。）
コード生成
*
変更
Open API Spec
Stub
コード
実装
❌ 変更済みのStubを反映することはできない
*
❌ 定義が間違っていても自動反映はされない
変更
実際のコード


# Page. 11

![Page Image](https://bcdn.docswell.com/page/K7429PW1J1.jpg)

なぜ乖離が発生するのか？
ドキュメントが先の場合（コードが先であっても。。）


# Page. 12

![Page Image](https://bcdn.docswell.com/page/LJ1MK9Y5EG.jpg)

なぜ乖離が発生するのか？
ドキュメントが先の場合（コードが先であっても。。）


# Page. 13

![Page Image](https://bcdn.docswell.com/page/GJW3DQGWJ2.jpg)

なぜ乖離が発生するのか？
ドキュメントが先の場合（コードが先であっても。。）


# Page. 14

![Page Image](https://bcdn.docswell.com/page/4EZVGWL2J3.jpg)

つらい、、


# Page. 15

![Page Image](https://bcdn.docswell.com/page/Y765YGM6EV.jpg)

なぜ？


# Page. 16

![Page Image](https://bcdn.docswell.com/page/G75YGVZ574.jpg)

スキーマとコードとの距離が離れてしまっている
独立したものになっていて、乖離が発生したことを見落としがち
コード生成
Open API Spec
Stub
コード
ココ!!
実装
実際のコード


# Page. 17

![Page Image](https://bcdn.docswell.com/page/9J2GY3RGJR.jpg)

どうすれば距離が縮まるか？


# Page. 18

![Page Image](https://bcdn.docswell.com/page/DEYVG1DGEM.jpg)

スキーマ定義をコードに埋め込むという方法
swagger-php のAttributeを使ってスキーマを定義する
Controller
Request
&lt;?php
&lt;?php
use OpenApi\Attributes as OA;
use OpenApi\Attributes as OA;
use Illuminate\Foundation\Http\FormRequest;
#[OA\Info(title: &quot;My First API&quot;, version: &quot;0.1&quot;)]
class OpenApi {}
class MyController {
}
#[OA\Get(path: &#039;/api/data.json&#039;)]
#[OA\Response(response: &#039;200&#039;, description: &#039;The data&#039;)]
public function getResource() {
// ...
}
ユーザー生成のリクエ
#[OA\Schema(schema: &#039;CreateUserRequest&#039;, title: &#039;
class CreateUserRequest extends FromRequest
{
use BaseRequestTrait;
ユーザー名
#[OA\Property(&#039;username&#039;, description: &#039;
&#039;,
type: &#039;string&#039;, maxLength: 100,
pattern: &#039;^[a-zA-Z\d]{4,100}&#039;, example: &#039;scott&#039;,
nullable: false)]
public string $username;
メールアドレス
#[OA\Property(&#039;email&#039;, description: &#039;
&#039;,
type: &#039;string&#039;, maxLength: 320,
pattern: &#039;^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zAexample: &#039;abc@example.com&#039;,nullable: false)]
public string $email;


# Page. 19

![Page Image](https://bcdn.docswell.com/page/VJNMG26878.jpg)

レビューしやすい
視点移動が少なくて済む


# Page. 20

![Page Image](https://bcdn.docswell.com/page/YE9NW1LXE3.jpg)

絶対スキーマから乖離させないマン
Attributeや実際に出力されたスキーマファイルを活用してスキーマとコードを乖離させない仕組み


# Page. 21

![Page Image](https://bcdn.docswell.com/page/GE8KN4X97D.jpg)

Attributeの力を引き出してみる!


# Page. 22

![Page Image](https://bcdn.docswell.com/page/LELZP68MJR.jpg)

Arttibuteはコードの一部！
ReflectionClassを使ってArttibuteを読み出してゴニョゴニョする


# Page. 23

![Page Image](https://bcdn.docswell.com/page/4JMV4566JW.jpg)

Arttibuteはコードの一部！
ReflectionClassを使ってArttibuteを読み出してゴニョゴニョする
スキーマファイル
生成
実際のコード
Controllerクラス
クラス
Request
Attribute
定義
Attribute
クラス
Response
Attribute
定義
定義


# Page. 24

![Page Image](https://bcdn.docswell.com/page/PJR2W3PNE9.jpg)

Arttibuteはコードの一部！
ReflectionClassを使ってArttibuteを読み出してゴニョゴニョする
スキーマファイル
生成 ズレが発生しない
実際のコード
Controllerクラス
Attribute
定義
自動生成
クラス
Request
実行時評価
Validation
ルール
Attribute
定義
クラス
Response
Attribute
定義
ファイル
Route


# Page. 25

![Page Image](https://bcdn.docswell.com/page/PEXDP4387X.jpg)

Arttibuteはコードの一部！
ReflectionClassを使ってArttibuteを読み出してゴニョゴニョする
スキーマファイル
生成 ズレが発生しない
実際のコード
Controllerクラス
Attribute
定義
自動生成
クラス
Request
実行時評価
Validation
ルール
Attribute
定義
クラス
Response
Attribute
定義
ファイル
Route


# Page. 26

![Page Image](https://bcdn.docswell.com/page/3EKXDZYL7D.jpg)

スキーマ自体も静的解析すべし！
OpenAPI Spec
Redoc
整形
スキーマファイル
swagge-ui
静的解析 生成
表示
spectral
swagger-php(L5-Swagger)
require
実際のコード
Controllerクラス
Attribute
定義
自動生成
クラス
Request
実行時評価
Validation
ルール
Attribute
定義
クラス
Response
Attribute
定義
ファイル
Route


# Page. 27

![Page Image](https://bcdn.docswell.com/page/L735RD96E5.jpg)

リクエスト・レスポンスの正確性を保証させる
Controllerテストで laravel-openapi-validator を利用してリクエストとレスポンスを検証
スキーマファイル
生成
自動生成
Controller
クラス
実際のコード
Routeファイル
クラス
Request
実行時評価
Validation
ルール
クラス
Response
テスト実行
コード
テスト(PHPUnit)
Test
Controller
Use
laravel-openapi-validator
参照（リクエスト・レスポンスValidation）


# Page. 28

![Page Image](https://bcdn.docswell.com/page/87DDYPGM7G.jpg)

より確実にE2Eで検証
APIシナリオテスト（ runn ）でユースケースを網羅的に検証
スキーマファイル
生成
自動生成
Controller
クラス
実際のコード
Routeファイル
クラス
Request
実行時評価
Validation
ルール
クラス
Response
テスト実行
API
Testコード
シナリオテスト(runn)
参照（リクエスト・レスポンスValidation）


# Page. 29

![Page Image](https://bcdn.docswell.com/page/VJPX6N3Q78.jpg)

まとめ


# Page. 30

![Page Image](https://bcdn.docswell.com/page/2EVL3K4PJQ.jpg)

スキーマ≠ドキュメント
スキーマはコードの一部。ドキュメンテーションツールからSpecを自動生成


# Page. 31

![Page Image](https://bcdn.docswell.com/page/57GX3Q1QEL.jpg)

スキーマをいつ書くか？
コードを書いたら勝手にスキーマ定義がいい感じに出力されている状態


# Page. 32

![Page Image](https://bcdn.docswell.com/page/4EQ85KDWJP.jpg)

スキーマ自体もテストが必要
静的解析して最低限の品質を確保
テストでの検証にも利用してスキーマを含んだAPI自体の品質も向上させる


# Page. 33

![Page Image](https://bcdn.docswell.com/page/KJ429PZ1E1.jpg)

参考URL
実装と乖離させないスキーマ駆動開発フロー / OpenAPI Laravel編
https://zenn.dev/katzumi/articles/schema-driven-development-flow
swagger-php
https://github.com/zircote/swagger-php
spectral
https://github.com/stoplightio/spectral
laravel-openapi-validator
https://github.com/kirschbaum-development/laravel-openapi-validator
runn
https://github.com/k1LoW/runn


# Page. 34

![Page Image](https://bcdn.docswell.com/page/LE1MK9R57G.jpg)

ご清聴ありがとうございます


