Slide 1

Slide 1 text

OpenAPIでチーム開発を加速させる 株式会社ラクス 水野 友輔 2024/05/22 フロントエンドLT会 - vol.9

Slide 2

Slide 2 text

APIドキュメントって書いていますか? 🤔

Slide 3

Slide 3 text

あるある 🔥 実装と仕様が乖離している 🔥 メンテされないまま放置💀 🔥 バージョニングなんて知らない 👊 最新版が正義 🔥 ドキュメント?コード見ればわかるじゃん(笑)

Slide 4

Slide 4 text

嬉しい状態 🔥 実装と仕様が乖離している 🔥 メンテされないまま放置 💀 🔥 バージョニングなんて知らない 👊 最新版が正義 🔥 ドキュメント?コード見ればわかるじゃん (笑) 👉 ドキュメントが実装と一致している (メンテされている) 👉 APIと同じくバージョニングが行われている 👉 ドキュメントをコードとして表現することが可能である

Slide 5

Slide 5 text

フロントエンド開発におけるAPIドキュメントの役割 1. どのエンドポイントに対して 2. どのような操作を行うもので (GET, POST, PATCH, PUT, DELETE…) 3. リクエストで何を投げたら 4. レスポンスで何が返ってくるか (+ エラーは何が発生し得るか ) を知ることができれば OK💡

Slide 6

Slide 6 text

👉 REST APIドキュメントのフォーマット そのためのOpenAPI Specification (旧: Swagger) TypeScriptっぽく書けるTypeSpecが最近話題

Slide 7

Slide 7 text

ドキュメントとコードを等しくメンテナンスする

Slide 8

Slide 8 text

● OpenAPI Generator ● Kiota ● aspida ● openapi-typescript ● openapi-zod-client etc… ● zod-to-openapi ● ts-rest (zod-openapi) ● TypeDoc etc… Docs to Code Code to Docs

Slide 9

Slide 9 text

● OpenAPI Generator ● Kiota ● aspida ● openapi-typescript ● openapi-zod-client etc… ● zod-to-openapi ● ts-rest (zod-openapi) ● TypeDoc etc… Docs to Code Code to Docs 👈

Slide 10

Slide 10 text

OpenAPITools/openapi-generatorについてざっくり ● OpenAPI(yaml/json)からコード・ドキュメント・ス タブサーバの生成が可能 ● nodeで利用可能なラッパーライブラリ (openapi-generator-cli)が提供されている ● サポートしている言語・フレームワークが豊富で カスタマイズ(mustache)も可能

Slide 11

Slide 11 text

● OpenAPIファーストな開発フロー ● バックエンド / フロントエンドで言語仕様が異なる ○ バックエンド: Kotlin, フロントエンド: TypeScript みたいなケース ○ でもコード生成のツールチェインは揃えておきたい ● 痒いところに手を届かせてくれそうなmustache ● 捨てやすさ ○ アプリケーションコードのノイズの少なさ => 実装と疎結合 ○ パッケージ化の容易さ OpenAPI Generatorを選ぶ理由

Slide 12

Slide 12 text

OpenAPIがクライアントコードになるまで

Slide 13

Slide 13 text

Reactプロジェクトの例 OpenAPI GitHub Packages (npm registry) React Project # クライアントコードの生成 + publish $ openapi-generator-cli generate $ npm publish # プロジェクトに packageを入れる $ npm install generated-package

Slide 14

Slide 14 text

これが...

Slide 15

Slide 15 text

こうなる 👀

Slide 16

Slide 16 text

importして使える👌

Slide 17

Slide 17 text

コード生成の嬉しいところ ● クライアントコードとOpenAPIが完全同期 🔄 ○ どのバージョンでどこが変更されたのかコードレベルで追える ○ OpenAPI / 生成したコードもGitHubでRelease/Tags管理 ● さらば手作業 👋 ○ API仕様書のインターフェイス定義をそのままコードに写経する必要無し ○ typo, required/nullable漏れのようなヒューマンエラーとは無縁 ● OpenAPIの内容が正 ✨ ○ 言語仕様を細かく気にする必要が無い undefined/null/blank ⇔ required/nullable/minLength:1 みたいなやつ ○ REST APIを正しく設計する文化が自然と定着する

Slide 18

Slide 18 text

おしまい 🎉 ...とはならず

Slide 19

Slide 19 text

UI Component / Formで扱う型との乖離

Slide 20

Slide 20 text

機能に関わるほぼ全てのinterfaceがOpenAPIに依存する ● extends, Pick, Omitは無限にあるのに、元の型はプロジェクト内で定義されない (node_modulesの *.d.tsを参照するから) ● 元の型に変更が入る => その型を拡張している型も... 👎 ソースコード全体の見通しが悪くなる 👎 OpenAPI依存の型を使用する箇所の修正に時間がかかる

Slide 21

Slide 21 text

OpenAPIの更新と機能実装が非同期 Publishしたよ〜 < すぐにバージョン上げたい 󰢧 < 型イカれるからちょっと待って 󰢃💦 < mainにマージされるまで実装しません 🙈 ブランチ/PR毎に状況が異なる

Slide 22

Slide 22 text

開発を回し続けるための工夫

Slide 23

Slide 23 text

最初に壊れるのはどこ? 1. ComponentProps, query, mutationが OpenAPIのinterfaceに依存する 🔥コンポーネントのType Error 2. PromiseとAxiosPromiseの間で interfaceの整合性を取る 🔥HttpRequestメソッドのType Error

Slide 24

Slide 24 text

HttpRequest / Responseのinterfaceを分離する プロジェクトで必要な型を定義 パッケージから型をimportする箇所を制限 +

Slide 25

Slide 25 text

“一旦” 壊れてもいいところを決めておく

Slide 26

Slide 26 text

型の恩恵を最大限に受けよう msw, テストコードのfixtureも生成した型で縛れる

Slide 27

Slide 27 text

「実装を中断しなくていい」は正義 💪 OpenAPIの更新を取り込む + packageのpublish packageのバージョンを上げる + トランスパイルエラーを回避するための暫定修正 暫定修正した箇所の対応 ● コンポーネントの実装に影響しない ● 「一箇所変わったら全部壊れる」を回避できる ● OpenAPI ⇔ Form ⇔ UIの型の乖離は HttpRequestメソッドで吸収できる

Slide 28

Slide 28 text

● OpenAPIはバックエンド / フロントエンドを並行で開発するために必要な共通資産 実装と同等にメンテナンスされるべき ● バックエンド / フロントエンドの分離開発において、Docs to Code / Code to Docs のような方法は有効 ● REST APIとUIで、interfaceは別定義の方が嬉しい場面もある。開発フェーズ・チー ム構成に合わせてやり方を変えていくのも大事 まとめ

Slide 29

Slide 29 text

素敵なスキーマ駆動開発ライフを 🎉

Slide 30

Slide 30 text

ちょいちょい登場していたリポジトリ https://github.com/hairihou/openapi-generator-example ※GitHub: QR (https://ohno.github.io/github-qr/)を使用しています 参考記事: https://zenn.dev/ohno/articles/295201bf0e64ce