Slide 1

Slide 1 text

© LayerX Inc. Webフロントエンドにおける GraphQL(あるいはバックエンドのAPI)との向き合い方 2024-11-06 #241106_plk_frontend @izumin5210

Slide 2

Slide 2 text

© LayerX Inc. 2 ▸ Wantedly, Inc. (2018-04 - 2022-08) ▸ LayerX (2022-09-) ‐ バクラク事業部 Platform Engineering 部 Enabling Team ‐ Web Frontend と Backend をやっています ▸ 好きな ESLint rule は no-restricted-syntax 画像を入れてね whoami @izumin5210

Slide 3

Slide 3 text

© LayerX Inc. 3 ▸ プロダクト: お客様に1つのパッケージとして価値を提供するソフトウェア製品 ‐ (「バクラク申請」など、右下の図における ○ を指すイメージ) ▸ サービス: 論理的あるいは物理的に分けられた1つのサーバアプリケーション ‐ 誤解を恐れずにいうと、マイクロサービス・アーキテクチャにおける 「サービス」という単語と概ね同等 ▸ API: サービスが他のプロセスとやりとりするための API ‐ いわゆる Web API (?) ‐ 本発表では 3rd party 向けのものは考えない 発表内での用語の定義 今日の話の前提: 用語の定義

Slide 4

Slide 4 text

© LayerX Inc. 4 ▸ Web フロントエンドが依存する “API” について、 それをなぜ・どうやって選ぶか、あるいは選ばれているか について考える ‐ + バクラクでどういう背景で、どういう選択をしたか ▸ バクラクで採用されている GraphQL について、 Web Frontend でその力を引き出すためにどういう思考をしたか ‐ + 具体的になにやったか 一例 今日話すこと 今日話すこと

Slide 5

Slide 5 text

API まわりの技術をどう選択するか どう選択するか, あるいはどう選択されるか

Slide 6

Slide 6 text

6 © LayerX Inc. “API”っていろいろある そもそもAPIなんか作らんぞ! (Server Components から頑張る) OpenAPI gRPC-Web Connect RPC Hono RPC tRPC GraphQL 技術 リソース指向 UI指向 (Server Driven UI) スキーマ設計 BFF Gateway バックエンドに 直つなぎ アーキテクチャ どう選ぶ?

Slide 7

Slide 7 text

7 © LayerX Inc. 選ぶための観点 ▸ API は様々なものの境界である ‐ プロダクトとプロダクト, チームとチーム, 技術領域と技術領域, 開発者と開発者 ‐ 一般に、「境界をまたぐ」行為はオーバーヘッドを伴いやすい ▸ (Web)フロントエンドだけで決められることではない かといってバックエンドに完全お任せというわけにもいかない API 技術、どうやって選ぶか

Slide 8

Slide 8 text

8 © LayerX Inc. 選ぶための観点 プロダクト構成 開発チームの設計 プロダクトの性質 いろんな観点で考えてみる

Slide 9

Slide 9 text

9 © LayerX Inc. 選ぶための観点 ▸ 「プロダクト」はいくつ? それぞれの関係は? ‐ 単一プロダクトなのか、シリーズなのか ‐ 独立したプロダクトなのか, プロダクト同士が連携するか ▸ 「フロントエンド」「クライアント」はどれくらいある? ‐ シリーズごとに Web Frontend アプリケーションを分けるかどうか ‐ モバイルアプリはあるか 観点の例 - プロダクト構成

Slide 10

Slide 10 text

10 © LayerX Inc. 選ぶための観点 ▸ ドメインの複雑さ ▸ UI の複雑さ ‐ 複雑にも種類はある: e.g. フロントエンドで難しいロジックを持たざるをえない, そもそも高度なGUI ▸ 変更頻度・変更可能性・フェーズ ‐ 複雑なドメイン × 開発初期 = 仕様も不安定で無限スクラップアンドビルド…かもしれない 観点の例 - プロダクトの性質

Slide 11

Slide 11 text

11 © LayerX Inc. 選ぶための観点 ▸ チームの構成・役割分担 ‐ 技術領域(Backend, Web Frontend)でチームがわかれる ‐ フルサイクルチーム(1つのチームでぜんぶやる) ‐ フルサイクルエンジニア(ひとりひとりがぜんぶやる) ▸ 規模感 ‐ どれくらいのプロダクトがあって、どれくらいチームができるか 観点の例 - 開発チームの設計

Slide 12

Slide 12 text

バクラクの API 前提になるプロダクト「バクラク」とアーキテクチャ概要

Slide 13

Slide 13 text

13 © LayerX Inc. 前提: バクラクについて LayerX Company Deck https://speakerdeck.com/layerx/company-deck?slide=24

Slide 14

Slide 14 text

© LayerX Inc. 14 ▸ プロダクトは toB, 複数, プロダクト間で機能・データの連携がある ‐ 1つのデータ空間を持つ、一連のシリーズあるいはプラットフォームになっているイメージ ‐ toB でドメインも複雑になりがちなで、そこにかかる思考のリソースは大きい ▸ フロントエンドも複数 ‐ モバイルアプリもあるし, 前述の通りプロダクト間の連携もある ▸ チームはフルサイクルエンジニアの集合体 ‐ もちろん技術領域の得意不得意を鑑みた分担もするが、基本は個々人がフルサイクル ‐ ひとつひとつのチームのサイズはちいさめ バクラクは? バクラクにおける API 技術選定の観点

Slide 15

Slide 15 text

© LayerX Inc. 15 ▸ 汎用的かつドメイン知識を持ったAPIを作る モチベーションがある ‐ 複数のクライアントがある ‐ 「申請者の”部署”」「このクレジットカードを持つ”部署”」のように 様々なオブジェクトと関連を持つオブジェクトが多く、 オブジェクトグラフを作れる GraphQL が活かしやすい ▸ 一方で… ‐ 規模が小さいかつフルサイクルエンジニアの集まりで、 BFF は too much になりがち ‐ モバイルもあるので tRPC など TypeScript 全部のせ系は難しい バクラクは? バクラクにおける API 技術選定の観点 GraphQL リソース指向 Gateway

Slide 16

Slide 16 text

GraphQL と Web フロントエンド GraphQL Gateway の思想を理解して設計・実装に組み込む

Slide 17

Slide 17 text

© LayerX Inc. 17 どうやって GraphQL や Gateway を活かすか GraphQL と Web フロントエンド ▸ GraphQL という技術の特性と、その採用された周辺アーキテクチャ、 選定の背景を深堀りして、それらによるメリットをうまく引き出す ‐ “GraphQL” の部分はお使いの技術に置き換えて考えてみてください ▸ いろんな観点や考えられることがあるけど… 今回は GraphQL を題材に考えの掘り下げ方を1例だけ紹介 ‐ GraphQL を使うときのアレコレはいくらでも話せる・話したいことあるので、懇親会で捕まえてください

Slide 18

Slide 18 text

© LayerX Inc. 18 ▸ パフォーマンスメリット ‐ 選択的なデータ取得による、overfetch や undefetch の解消 ‐ 従来の REST API だと複数の fetch になっていたものが1つにまとめられることによる、 通信回数の削減や waterfall の回避 ▸ 開発体験・保守性 ‐ スキーマを通じてデータの構造が明確になり、 TypeScript などの型も生成できる ‐ スキーマ自体が自然言語によらない、機械同士・人間同士いずれのコミュニケーションにも使えるプロトコルとなる ‐ Lint, Breaking Change 検知, 補完, Playground などサポートが充実 ▸ etc. GraphQL という技術の特性・そこから得られるもの GraphQL と Web フロントエンド

Slide 19

Slide 19 text

© LayerX Inc. 19 ▸ パフォーマンスメリット ‐ 選択的なデータ取得による、overfetch や undefetch の解消 ‐ 従来の REST API だと複数の fetch になっていたものが1つにまとめられることによる、 通信回数の削減や waterfall の回避 ▸ 開発体験・保守性 ‐ スキーマを通じてデータの構造が明確になり、 TypeScript などの型も生成できる ‐ スキーマ自体が自然言語によらない、機械同士・人間同士いずれのコミュニケーションにも使えるプロトコルとなる ‐ Lint, Breaking Change 検知, 補完, Playground などサポートが充実 ▸ etc. GraphQL という技術の特性・そこから得られるもの GraphQL と Web フロントエンド

Slide 20

Slide 20 text

© LayerX Inc. 20 ▸ パフォーマンスメリット ‐ 選択的なデータ取得による、overfetch や undefetch の解消 ‐ 従来の REST API だと複数の fetch になっていたものが1つにまとめられることによる、 通信回数の削減や waterfall の回避 ▸ この “選択的データ取得” はパフォーマンス観点で語られがちだけど、 掘り下げていくと設計上も上も重要なポイントになる ‐ まさに “グラフ” であると考えていく GraphQL という技術の特性・得られるもの GraphQL と Web フロントエンド

Slide 21

Slide 21 text

© LayerX Inc. 21 フルサイズのグラフから、 必要なデータに絞ったサブグラフ(木?)を取り出す 選択的データ取得 #とは

Slide 22

Slide 22 text

© LayerX Inc. 22 更に、特定の部分に絞った サブサブグラフ(?)を定義できる 👉 Fragment

Slide 23

Slide 23 text

© LayerX Inc. 23 コンポーネント(UIに限らず)ごとに必要なデータを Fragment として記述 👉 Fragment Colocation

Slide 24

Slide 24 text

© LayerX Inc. 24 ▸ コンポーネントが依存するのは API ではなくオブジェクトになる ‐ (ドメイン)オブジェクトに向き合う力学が働く ▸ 利用状況トレーサビリティの向上 ‐ バックエンドから見たとき、 「どのコンポーネントで使われているか」という 非常に解像度の高いトレースになる グラフ, 選択的データ取得, Fragment Colocation で 得られるもの

Slide 25

Slide 25 text

© LayerX Inc. 25 ▸ GraphQL は “オブジェクトのグラフ” を提供する ‐ そのグラフのサブセットに、アプリケーションや個々のコンポーネントが依存していく ‐ APIやオペレーションへの依存ではなく、サブグラフ = (ドメイン)オブジェクト への依存へ ▸ バクラク(toB, 複数プロダクト)では同じグラフを見ていることが活きやすい ‐ あるプロダクト実装時に繋いだグラフ(エッジ)が、別のプロダクトでも生きる ‐ また、たとえばプロダクトをまたいだ共通のコンポーネントが依存オブジェクトを Fragment で持っていれば、 それぞれのプロダクトの fetch に共通コンポーネントも紛れ込ませることができる ■ 依存はオブジェクトのままだが、データ取得へのつなぎ込みがしやすくなる GraphQL を活かす設計例: グラフ・選択的データ取得を活かす GraphQL と Web フロントエンド

Slide 26

Slide 26 text

© LayerX Inc. 26 どうやって GraphQL や Gateway を活かすか GraphQL と Web フロントエンド ▸ 再掲: GraphQL という技術の特性と、採用された周辺アーキテクチャ、 選定の背景を考えて、それらによるメリットをうまく引き出す ‐ “GraphQL” の部分はお使いの技術に置き換えて考えてみてください ▸ こんな感じで技術や背景から深堀りしていって、 自分たちの選定にあった設計を考え当てはめていくことで技術を活かしていく ‐ おまけ: Why から詰めていくことで、「今の時代は〇〇じゃなくて△△じゃない?」みたいな話でも 意義のある議論ができるようになる(そして、本当にそうなったときの移行の必要性の議論もしやすくなる)

Slide 27

Slide 27 text

まとめ

Slide 28

Slide 28 text

© LayerX Inc. 28 まとめ API技術選定・設計における考え方や観点の一例を紹介した ▸ 技術自体の性質や一般的な選定における観点に加え、 プロダクト自体の構成, プロダクトの性質, チームの構成 などなど、APIならではの観点がある ▸ バクラクでは GraphQL Gateway を作り、シリーズの各プロダクトが利用する形を取っている API技術を活かす例として、GraphQLを Web Frontend で使うときに考えたこと(一部) ▸ GraphQL という技術の特性と採用したアーキテクチャ、選定の背景を考え、 技術の力を引き出すための考察を深めるアクションの例を紹介した ▸ 具体例: ある程度汎用なグラフ, Fragment による API 依存 → オブジェクト依存への転換 etc.