出前館Webフロントエンドにおけるリプレイスプロジェクトの取り組みと反省株式会社出前館Taiki Shiraishi / 白石 泰己
View Slide
自己紹介株式会社出前館フロントエンドグループ グループマネージャーTaiki Shiraishi / 白石泰己ユーザー向け Web サイト開発UI制作が好きなフロントエンドエンジニア
● 個人発表ではなくチームを代表して発表● チームの取り組んできた内容について● チーム構成 12 名発表の内容について
12345目次PHP から Next.js への刷新BFF パターンの採用GraphQL の採用モノレポの採用コンポーネントディレクトリの変更
出前館 Web フロントエンドリプレイス● 開発体制の内製化● フロントエンドチーム● 2021年からビッグ・リライト中● PHP + jQueryからNext.jsへの刷新○ より効率的な開発が可能内製化 技術刷新
出前館 Web フロントエンドリプレイスBeforeBrowser PHPAppLegacy APIRedis DB
出前館 Web フロントエンドリプレースAfterBrowser BFFAppLegacy APIRedis DBMicroService AMicroService B
1234PHPからNext.jsへの刷新理由フロントエンドチームに PHP 知見ある人が少なかった既存のコードの保守性の問題MVCフレームワークでありながらControllerが肥大化内製化によるPHPの知識不足フロントエンドのベストプラクティスを適用しやすい環境にバグを減らして、できるだけ早くコードをリリースしたいSSG、SSR、 CSRを同時にできるフレームワークは当時は一択採用活動にも有利Reactコミュニティの大きさ
Next.js に満足
123BFF(Backend For Frontend)パターンの採用理由バックエンドのマイクロサービス化セッション管理PHP で行っていたセッション管理の構成を引き継ぐAggregation Gateway層の必要性アプリと Web で処理が重複 → BFF で共通化● 待ち時間の計算● 店舗の商品の時間帯別ソート● 暗号化/復号化アプリと Web で 1 つの BFF にすることとしたモバイルアプリと Web のロジックの共通化
Good 👍BFFパターンの採用 その後● ViewModel の共通化● テストコードもかけた● フロントチームだけで整形を完結できる● 開発組織内でも責務の認識齟齬○ ビジネスロジックを持ちオーケストレーション層だと思われる● アプリの改修時にもフロントエンドチームの稼働が発生● フロントエンドエンジニアがインフラを構築・運用管理したり、オブザーバビリティをきちんとするまでにいたるのには大変● 今までブラウザサイドの経験しかないメンバーでやるのは大変One more 😒
One more 😒● 開発組織内でも責務の認識齟齬○ ビジネスロジックを持ちオーケストレーション層だと思われる● アプリの改修時にもフロントエンドチームの稼働が発生● フロントエンドエンジニアがインフラを構築・運用管理したり、オブザーバビリティをきちんとするまでにいたるのには大変● 今までブラウザサイドの経験しかないメンバーでやるのは大変● BFF という名前が一人歩きしないようにコミュニケーションがアーキテクチャ図を作るべきだった● Web チームがアプリの人を巻き込んで作るべきだった● 初期構築時にインフラエンジニアがチームにいてほしかった● オブザーバビリティに知見のある人が欲しかったIdeal ✨BFFパターンの採用 その後
12GraphQLの採用理由アプリと Web 両方から利用されるため柔軟に利用できるようにデータオーバーフェッチの削減リクエストの最適化クライアントドリブンなアプローチ
Good 👍GraphQL採用 その後● ApolloClient のキャッシュが良い○ SPA 遷移したときにリフェッチせずキャッシュが優先される● 既存 API の設計に依存し再利用性と柔軟性が低い○ GraphQL のベストプラクティスを実現できていない。○ 昔の DB のデータ構造や API の改修になしにGraphQL サーバーだけでは柔軟なデータ構造の構築には至れなかった● REST API と変わらぬ設計One more 😒
One more 😒GraphQL採用 その後● 既存 API の設計に依存し再利用性と柔軟性が低い○ GraphQL のベストプラクティスを実現できていない。○ 昔の DB のデータ構造や API の改修になしにGraphQL サーバーだけでは柔軟なデータ構造の構築には至れなかった● REST API と変わらぬ設計● DB~マイクロサービス まで 1 チームとなりデータ構造を作りたかった● これからのリアーキテクトに期待Ideal ✨
123monorepo の採用理由SSRと BFF の負荷を分散することで可用性 UPリスク分散別サーバーにすることで Web サーバーが動かなくとも BFF が動けばアプリは動く負荷分散Next.js の API routes だったため、クライアントサイドとサーバーサイドのコードが混在より明確なコードベースとディレクトリ構造
Good 👍monorepo 採用 その後● パフォーマンス向上● 実際に Web で障害が発生したが、 BFFは稼働し続けた● クライアントサイドとサーバーサイドでコードベースが分離されてわかりやすく● Web と同じリポジトリの場合に他チームがカジュアルに参加できない● クライアントとサーバーで util 関数などが共通化できておらず、monorepo の良さを活かしきれていないOne more 😒
One more 😒monorepo 採用 その後● Web と同じリポジトリの場合に他チームがカジュアルに参加できない● クライアントとサーバーで util 関数などが共通化できておらず、monorepo の良さを活かしきれていない● 完全な別リポジトリにすべきだった● monorepo での共通関数の modules 作成を最初にすべきだったIdeal ✨
BeforeComponent ディレクトリの変更src└─components├─atoms├─molecules├─organisms├─templates└─pages1. Atomic design の粒度と React Componentの粒度が合わないa. Headless な UI はどうすれば🤔2. Templates と Layouts が役割が重複しているa. Pages も同じくOne more 😒
AfterComponent ディレクトリの変更src├ shared ……………………………… # 特定の機能に関心を持たない汎用モジュール群│ ├ components│ │ ├ functionals ………………… # 見た目に対して関心を持たないコンポーネント群│ │ └ ui ……………………………… # その他の汎用コンポーネント│ └ hooks ……………………………… # 汎用hooks└ features ……………………………… # 特定の機能に関心を持つモジュール群├ shop│ ├ components│ └ hooks└ cart├ components└hooks
1234改善できる背景GitHub Discussion や MTG の開催で新しい取り組みへ前向きに議論毎週木金に翌週リリースの資材でコア機能のテストチームでの議論QA によるリリース判定テストフロントチームも取り組んでいるがサーバーチームからも報告があるオブザーバビリティ自分たちで使って自分たちで直す社員にユーザーがいる
● チーム内の認識合わせの重要性● ビジネス変化や考慮不足による負債は不可避● 改善と組織・環境の重要性● 新しい取り組みと慎重さのバランス感まとめ
ありがとうございました!ご質問などお気軽にお尋ねください。😄