Upgrade to Pro — share decks privately, control downloads, hide ads and more …

あえてスキーマ駆動開発を見送った話

 あえてスキーマ駆動開発を見送った話

「泥くさい課題と向き合うフロントエンド KINTOテクノロジーズ with MixLeap Study」で発表したスライドです。
https://kinto-technologies.connpass.com/event/352670/

More Decks by KINTOテクノロジーズ Osaka Tech Lab

Transcript

  1. プロジェクトでの OpenAPI の状態 • 設計フェーズで OpenAPI を作成 • つまり開発時点で OpenAPI

    が存在していた • 開発後はバックエンドから OpenAPI を出力し、最新化していく • いわゆるコードファーストな形 • なので、フロントエンドはいつでも OpenAPI からコード生成できる状態だった ⇒スキーマ駆動開発のチャンス
  2. プロジェクトでの OpenAPI の状態 • 設計フェーズで OpenAPI を作成 • つまり開発時点で OpenAPI

    が存在していた • 開発後はバックエンドから OpenAPI を出力し、最新化していく • いわゆるコードファーストな形 • なので、フロントエンドはいつでも OpenAPI からコード生成できる状態だった ⇒スキーマ駆動開発のチャンス しかしこのプロジェクトでは スキーマ駆動開発を見送ることにしました
  3. スキーマ駆動開発を見送った理由 • 過去 PJ で感じた懸念を解決できていない • 方針を定めようにも、どういう形がベストなのかを落とし込めていない。 • 泥臭いが、いっそのこと手動で型定義した方がキレイかつ進めやすいのでは? •

    スキーマ駆動ゆえのトラブルを避けられる。 • 本当に必要な型定義を用意できる。 • スピードは落ちるが、長い目で見ても愚直に書いたほうがメリットなのでは。。。? • メンバー構成を見ても、自分がある程度変更を把握・コントロールできるので、逆に安全かも。。。
  4. スキーマ駆動開発を見送った結果、どうだったか? 開発速度の不安が強かったが、案外問題なかった。 その1 型定義が至るところに散らばることもなかった。 その2 API 仕様の変更にも問題なく追従できた。 その3 手書きサイコー! そんなわけなくない……?

    手書きしただけで なんでこんなに絶大な効果があるの……? 手書きを決断した自分が言うのもなんだけど、 これはさすがにおかしい…… 前回と今回の違いから 何がうまくいったのかを考えてみたい
  5. 前回と今回のプロジェクトの比較 前回 • スクラム開発で変更が多い • フロントエンド・バックエンドが分業で 共通言語が必要→OpenAPI が必要 • だからスキーマ駆動開発は間違いではな

    かったし、非常に効果があった ⇒負債化の懸念はさておき、スキーマ駆動 開発でなければ厳しかった 今回 • ウォーターフォールで変更が多くない • 自分が両方の開発に介在していた →OpenAPI がなくとも会話できる • 手書きにしたことで依存をなくし、上記 理由で開発スピードも落とさずに済んだ ⇒プロジェクトの特性と取った選択がうま くマッチした
  6. 前回と今回のプロジェクトの比較 前回 • スクラム開発で変更が多い • フロントエンド・バックエンドが分業で 共通言語が必要→OpenAPI が必要 • だからスキーマ駆動開発は間違いではな

    かったし、非常に効果があった ⇒負債化の懸念はさておき、スキーマ駆動 開発でなければ厳しかった 今回 • ウォーターフォールで変更が多くない • 自分が両方の開発に介在していた →OpenAPI がなくとも会話できる • 手書きにしたことで依存をなくし、上記 理由で開発スピードも落とさずに済んだ ⇒プロジェクトの特性と取った選択がうま くマッチした
  7. 前回と今回のプロジェクトの比較 前回 • スクラム開発で変更が多い • フロントエンド・バックエンドが分業で 共通言語が必要→OpenAPI が必要 • だからスキーマ駆動開発は間違いではな

    かったし、非常に効果があった ⇒負債化の懸念はさておき、スキーマ駆動 開発でなければ厳しかった 今回 • ウォーターフォールで変更が少ない • 自分が両方の開発に介在していた →OpenAPI がなくとも会話できる • 手書きにしたことで依存をなくし、上記 理由で開発スピードも落とさずに済んだ ⇒プロジェクトの特性と取った選択がうま くマッチした では前回のプロジェクトで感じた スキーマ駆動開発による負債化していく感覚は なんだったのだろう……? 今回のプロジェクトの効果を考えてみる
  8. (再掲)スキーマ駆動開発を見送った結果、どうだったか? Feature-Sliced Design というディレクトリ構成 で型定義を一箇所にまとめた。 また、ベースになるエンティティから Pick・ Omit を使うなどして必要な情報だけ渡し、 API

    変更に強く影響しないように工夫した。 型定義が至るところに 散らばることもなかった。 その 2 API 仕様の変更にも 問題なく追従できた。 その 3 Remix の clientLoader/clientAction 関数経由で fetch 関数を呼び出すようにしたことで、 腐敗防止層になってくれていた。
  9. (再掲)スキーマ駆動開発を見送った結果、どうだったか? Feature-Sliced Design というディレクトリ構成 で型定義を一箇所にまとめた。 また、ベースになるエンティティから Pick・ Omit を使うなどして必要な情報だけ渡し、 API

    変更に強く影響しないように工夫した。 型定義が至るところに 散らばることもなかった。 その 2 API 仕様の変更にも 問題なく追従できた。 その 3 Remix の clientLoader/clientAction 関数経由で fetch 関数を呼び出すようにしたことで、 腐敗防止層になってくれていた。
  10. (再掲)スキーマ駆動開発を見送った結果、どうだったか? Feature-Sliced Design というディレクトリ構成 で型定義を一箇所にまとめた。 また、ベースになるエンティティから Pick・ Omit を使うなどして必要な情報だけ渡し、 API

    変更に強く影響しないように工夫した。 型定義が至るところに 散らばることもなかった。 その 2 API 仕様の変更にも 問題なく追従できた。 その 3 Remix の clientLoader/clientAction 関数経由で fetch 関数を呼び出すようにしたことで、 腐敗防止層になってくれていた。 ということは、 自分にとってスキーマ駆動開発で ほしかったものは手書き型定義じゃなく、 ただの腐敗防止層的な役割だった……?
  11. 腐敗防止層の役割 API の レスポンス コンポーネン トなど API をコール fetch など

    API に依存する箇所 変換処理 (腐敗防止層) API への依存を 最小限に 安全な領域
  12. 今回のプロジェクトにあてはめると? API の レスポンス コンポーネン トなど fetch 関数 API に依存する箇所

    Remix loader/action フロントエンドが 要求する型 (手書きの型定義)に 変換 安全な領域
  13. 今回のプロジェクトにあてはめると? API の レスポンス コンポーネン トなど fetch 関数 API に依存する箇所

    Remix loader/action フロントエンドが 要求する型 (手書きの型定義)に 変換 安全な領域 たまたまうまくハマっただけだった…… 手書きだからうまくいったのではなくて、 いろんな要素が たまたまうまくハマっただけだった……
  14. そして次のプロジェクトへ…… • あらためてスキーマ駆動開発を取り入れる • フロントエンド・バックエンドで設計・開発が分業されている • OpenAPI ができた時点で一度 Orval のコード生成→正しい型になることを確認

    • Orval の恩恵を最大限受けられるよう TanStack Query を採用 • 型とカスタムフックは直接使わず、ラッパーおよび型変換処理を通して疎結合にする ⇒今後、どの程度の負担になるかは未知数だが、いまのところ大きな問題は起きていない スキーマ駆動開発のメリットも得られているのでそこまでの心配はない