目次
はじめに
こんにちは。食べログ開発本部アプリ開発部の小嶋です。 「食べログノート」という飲食店運営者向けのオンライン予約台帳サービスを開発しています。予約管理、顧客管理、空席在庫管理など、飲食店の運営に不可欠な機能を提供しており、機能開発・改善を継続的に行っています。
食べログノートではクライアントとサーバー間のインターフェースとしてGraphQLを採用しており、「スキーマドリブン開発」を実践しています。 スキーマドリブン開発とは、まず最初にAPIの仕様である「スキーマ」を定義し、そのスキーマを契約としてクライアントサイドとサーバーサイドが並行して各自の開発を進める手法です。これにより、インターフェースの齟齬や手戻りを減らし、開発効率を向上させることができます。 スキーマドリブン開発の基本的な考え方については、こちらの記事で詳しく解説していますので、ぜひご一読ください。
本記事では、このスキーマの運用を通じて見えてきたスキーマ設計の落とし穴とその解決策、そしてそこから得られた「スキーマをチーム間の共通言語として育てる」という文化について、私たちの実体験をもとにお話しします。 「スキーマの設計が人によってバラバラになる」「レビューが表層の指摘に終わってしまう」といった課題に向き合っている方にとって、チームを越えてスキーマ設計の共通認識を醸成するヒントになれば幸いです。
食べログノートの開発体制
食べログノートはWebブラウザ版とネイティブアプリ版(iOSアプリ、Androidアプリ)を提供しています。そのため、食べログノートの開発は、3つのチームに分かれて行われています。 バックエンド(サーバーサイド)を担当するBEチーム、Webブラウザ版のフロントエンドを担当するFEチーム、そしてネイティブアプリ版を担当するAPPチームです。
これら3チームはそれぞれ異なる部署に所属しており、部署横断的な体制のもとで、連携しながら開発を進めています。 私自身アプリ開発部だけでなく、一時期BEチームの部署に所属していたこともあり、クライアントサイドとサーバーサイド、どちらかに寄るのではなく中立的な視点でお話しできればと思います。
保たれていた秩序
GraphQLを導入した背景
食べログノートの開発当初、私たちはクライアントとサーバーのインターフェースとしてGraphQLの導入を決定しました。 食べログでは他にもいくつか関連サービスが存在しますが、GraphQLの導入は初の試みでした。
導入の理由は主に以下になります。
クライアント要求への柔軟性の向上
従来型のREST APIでは、多様なクライアント(Web/アプリ)や頻繁なUIの変更に対応するたびに、専用エンドポイントの乱立やレスポンスの過不足といった問題が発生し、サーバーサイドの負担が増大しがちでした。クライアント自身が必要なデータだけを過不足なく取得できるGraphQLの柔軟性が、この課題の解決に不可欠でした。
並行開発を促進する、スケーラブルな開発体制の確立
コアドメインを開発するチームに責務が集中する状況を解消し、開発組織全体をスケールさせる狙いもありました。GraphQLでAPI層を設けることにより、ビジネスの核となるロジックを実装する責務と、それをクライアントにどう見せるかというインターフェース設計の責務を分離し、開発の並行性を高めることを期待していました。
専任の管理者不在でGraphQLを運用
私たちのチームには、開発初期からGraphQLの管理を専任して行うチームは存在しません。あえて専任チームを置いてないというよりは専任チームがいなくてもうまくいっていたのでそのまま専任チームがいないまま運用され続けてきたという経緯があります。
その代わり、以下のような文化がありました。
- どのチームがスキーマ設計を担当しても良い
- 設計されたスキーマは、BE、FE、APPの三者間でレビューを行う
導入初期は、この運用で大きな問題は発生しませんでした。各チームのリーダーや設計能力の高いメンバーがレビュープロセスに深く関与し、彼らの知見によってスキーマの品質が保たれていたのです。この時期のスキーマは、私たちがソフトウェア化するドメインにおける概念(予約、顧客、卓など)や業務プロセスや業務ルール、つまりドメイン知識を的確に表現したものとして維持されていました。
開発拡大で露呈したスキーマ運用の課題
しかし、プロダクトの成長に伴い、開発プロジェクトが複数並行して走り、メンバーも増え、システム全体の複雑性が増す中で、この運用体制に潜んでいた課題が徐々に表面化し始めます。 「誰でもスキーマを設計できる」という自由さと「専任の管理者が不在」という運用体制が裏目に出始めたのです。
レビューコストの増大
スキーマを設計・レビューするメンバーには、ドメイン知識の深さや抽象化のスキルにばらつきがあるのは自然なことです。問題は、そのばらつきを是正するための設計の判断基準が存在しないことにありました。明確な拠り所がないため、設計は個人の解釈に大きく依存します。 チーム内で適切に軌道修正されれば問題ありませんが、そこをすり抜けてしまうと、チーム間レビューのフェーズで根本的な指摘が多発し、手戻りやコミュニケーションコストが大きくなっていきました。 これまでにもレビューのコストを抑えるために、命名規則といったスキーマのコーディング規約は整備してきました。しかし、それらは表面的な書き方の統一には有効でしたが、「何を、どのような思想で設計すべきか」という本質的な問いには答えてくれませんでした。
スキーマに対する認識のズレ
そもそもスキーマをどう設計すべきか、チーム間で統一された認識がなかったため、設計するチームによって設計思想が異なり、チーム間レビューのコストも膨らみました。 例えば以下のようなスキーマが挙げられます。
クライアントサイドの実装都合のスキーマ
クライアントサイドの実装、つまりUIコンポーネントの構造をそのまま反映したGraphQLスキーマは、クライアントとサーバーの密結合という問題を招きます。 このような設計では、UIの変更がスキーマの修正、ひいてはサーバーサイドや同じスキーマを利用する他媒体の改修にまで直結し、変更容易性を著しく低下させます。また、特定のUIに最適化されたスキーマは、他の画面や新たなユースケースでの再利用性を損なう大きな要因となります。 特に食べログノートでは、Webブラウザ版とiOSアプリとAndroidアプリで機能開発の優先度やタイミングが異なる、柔軟な開発体制をとっています。このような開発スタイルにおいては、将来にわたって複数の媒体でデータを共通利用できるよう、UIから独立した、再利用性の高いスキーマ設計が不可欠です。
サーバーサイドの実装都合のスキーマ
サーバーサイドの実装、つまりデータベース構造や内部APIの仕様をそのまま反映したスキーマは、クライアントサイドに不要な負担を強いるという問題を招きます。 このような設計では、クライアントサイドは生のデータからビジネスロジックを自前で計算したり、内部コードの意図を解釈したりする必要に迫られ、ロジックの重複や不整合の原因となります。その一方で、良かれと思った抽象化が粗すぎると、UIを構築する上で判断の根拠となる詳細な情報が失われ、クライアントでの柔軟な表現力を著しく損ないます。 特に食べログノートでは、媒体を横断して一貫したビジネスルールを保ちつつ、それぞれのUIに最適化したリッチな表現が求められます。
このように、チーム間で統一された認識がなかったため、「このスキーマはクライアントサイドに寄せるべきか、サーバーサイドに寄せるべきか」といった不毛な議論を生み、本質的な問題解決から遠ざかっていました。
スキーマを「チーム間の共通言語」にする
私たちはこの課題を解決するために、スキーマの役割を再定義することにしました。 それは、スキーマを単なるAPI仕様ではなく、「ドメイン知識をモデリングした、チーム間の共通言語」として明確に位置付けることです。 サービスのドメイン知識は、本来エンジニア全員が共有すべき普遍的な概念であり、だからこそ、立場を超えた共通言語となり得ると考えています。
この認識をチーム間で共有することで、スキーマドリブン開発は真価を発揮します。共通言語という揺るぎない指針があるからこそ、各エンジニアは自身の専門領域の開発に集中できます。UIの都合やリソースの都合といった部分的な視点ではなく、「サービスとしてどうあるべきか」という全体視点での対話が生まれます。
「疎結合」と「密なコミュニケーション」
優れたインターフェースは、互いの内部事情を知らない「疎結合」な状態を実現します。しかし真に価値のある疎結合は、お互いの「密なコミュニケーション」から生まれると信じています。
この密なコミュニケーションを阻害していたのが、これまでの開発プロセスでした。業務ロジックは基本的にサーバーサイドに責務があります。そのためその裏付けとなる業務プロセスや業務ルールの整理はサーバーサイドで行われることがほとんどです。クライアントサイドに共有されるのは、すでに固まった仕様だけ、というケースも少なくありませんでした。仕様の背景にある「なぜ」、つまり本質的な業務が共有されないまま開発が進むため、クライアントサイドはサーバーサイドの単なる窓口となり、与えられた仕様を実装する以上の価値を発揮しにくいという課題がありました。
これは逆も言えることで、クライアントサイド主導で機能が作られると、今度はその背景にある「どう使われるか(本質的なユースケース)」の整理がサーバーサイドに共有されないことがあります。その結果、サーバーサイドはパフォーマンスなどの技術的リスクを見過ごしたまま、単なるデータ供給装置に成り下がってしまいます。
スキーマを単なるAPI仕様書ではなく、「チーム間の共通言語」として育てるためには、開発プロセスを見直し、チーム間の密なコミュニケーションを促進することが不可欠でした。
密なコミュニケーションを促進するための取り組み
この課題を解決するために、私たちは以下の取り組みを徹底しました。
開発初期段階からの共同参画
3チームが共に要件定義の初期段階から参画します。重要なのは、どのチームが開発を主導するのか、どのチームの開発規模が大きいのかに関わらず、その根幹にあるドメイン知識やユースケース、技術的/外部的制約を全チームが共有、理解することです。この最上流での合意形成が、後工程で生じる認識のズレを防ぎ、全チームがドメインの本質を捉えた共通言語としてのスキーマを設計するための土台となります。
設計思想を問うスキーマレビュー
スキーマレビューを、単なる形式チェックの場にはしません。「このスキーマは、我々の共通言語として本当に適切か?」「この設計は、サービスとしての一貫性を保てているか?」といった、設計思想そのものを問い直す場としています。ここで生まれる食い違いは、表面的な修正で終わらせず、要件に立ち返って議論すべき重要なサインと捉えています。
共通言語がもたらした組織的な効果
スキーマを「共通言語」として捉え直したことで、私たちの開発チームにはいくつかのポジティブな変化が生まれました。
チーム間の認識統一
まず、「UIの都合」「リソースの都合」といった部分最適化の設計が減り、レビューでの根本的な手戻りが格段に少なくなりました。 さらに、全員が参照できる設計指針ができたことで、議論の質も変化しています。「このドメインの表現は、本当にこれで正しいのか?」といった、より本質的で建設的な議論ができるようになりました。
サービス理解の向上
これまでの開発体制では、要件定義からスキーマ設計までを同じチームが担当し、他のチームにはその背景や意図が十分に共有されないということがしばしばありました。その結果、スキーマレビューは設計思想にまで踏み込めず、表面的な「書き方」のチェックに留まりがちでした。 しかし、スキーマを「ドメイン知識をモデリングした共通言語」と位置付けたことで、この状況は変わりつつあります。ドメインのモデリングは、開発に関わる全てのエンジニアがサービスの要件を深く理解することを促します。エンジニアは単なる実装者ではなく、より上流の段階から「この機能は、私たちの共通言語でどう表現すべきか」を考える当事者へと意識が変化していくのです。この意識の変化が、チーム全体のプロダクトへの解像度を徐々に高め、これまで以上に活発な情報共有を生む、という好循環に繋がり始めています。
みんなで育てるという意識
また、サービスが進化し続ける中で、既存のスキーマが現状に合わなくなることもあります。そうした際には、誰かからの指示を待つのではなく、「ここの構造は、もっとこうした方が分かりやすいのでは?」といった改善提案が、各チームから自発的に生まれるようになりました。スキーマが特定の誰かの所有物ではなく、全員の「共有資産」であるというオーナーシップが、チーム全体に根付き始めているのを感じています。
おわりに
本記事では、食べログノートにおけるスキーマ運用の変遷を振り返りながら、スキーマを「ドメイン知識をモデリングしたチーム間の共通言語」として捉え直すことで得られた気づきや効果をご紹介しました。
GraphQLの専任管理者がいない状況でも、スキーマを共通言語とすることで、チーム間の認識のズレや不毛な議論を減らし、より本質的な対話が生まれるようになりました。 さらに、こうした対話を通じてチーム間のコミュニケーションやサービスへのコミットメントが促進され、「スキーマをみんなで育てる」という意識が、私たちの開発文化として根付き始めています。
今後は、チーム間の共通言語であるだけでなく、AIにとっても理解可能な構造化された知識としてスキーマの価値がさらに高まっていくと考えています。明確な構造と意味を持つスキーマは、自然言語では曖昧になりがちなドメイン知識をAIが扱いやすくする土台になります。こうした視点からも、スキーマを「みんなで育てる」という文化は、これからの開発において資産になるはずです。
本記事が、チームを越えてスキーマ設計と向き合う文化づくりのヒントとなれば幸いです。
食べログでは、共にプロダクトを育てていく仲間を募集しています。 興味を持っていただけたら、ぜひ採用ページもご覧ください。