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

GraphQL Client + 状態管理ライブラリを調査した話

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Watanabe Watanabe
January 31, 2024

GraphQL Client + 状態管理ライブラリを調査した話

Apollo Clientを利用しているプロダクト視点で、他のGraphQL Clientや状態管理ライブラリがどのような構成になっているか調査しました。

Avatar for Watanabe

Watanabe

January 31, 2024
Tweet

Other Decks in Technology

Transcript

  1. 名前 渡辺 瑞生 所属 動画配信開発部 プレミアムグループ 23年新卒 仕事 DMM TV

    (Webブラウザ) のフロントエンド開発・保守 X (Twitter) @shikachii 趣味 バイク・サウナ・シーシャ よく使う技術 React, Next.js, TypeScript
  2. アジェンダ - DMM TV (Webブラウザ) FEの技術構成 - Apollo Clientとは -

    気になる点 - ライブラリ調査 - GraphQL Client - 状態管理ライブラリ - まとめ - 宣伝 3
  3. 技術構成 4 Next.js フレームワーク Apollo Client GraphQL Client + 状態管理ライブラリ

    GraphQL Server フロントエンド データベース クライアント
  4. Apollo Clientとは - GraphQLを使⽤したリモート&ローカルデータの状態管理ライブラリ - スター数:19,118 (2024/1/28現在) 5 Apollo Client

    is a state management library that simplifies managing remote and local data with GraphQL. https://www.apollographql.com/docs/react/why-apollo より引用
  5. Normalized Cache(正規化キャッシュ) 6 { __typename: "Person", id: "hogehoge", name: "shikachii",

    company: { __typename: "Company", id: "fugafuga", name: "DMM.com" } } { __typename: "Person", id: "hogehoge", name: "shikachii", company: { __ref: "Company:fugafuga" } } { __typename: "Company", id: "fugafuga", name: "DMM.com" } 取得したデータ メモリ内キャッシュ 効率的なキャッシュの更新が可能
  6. Reactive Variables - Apollo Clientキャッシュから分離された外部のローカル状態を管理 7 import { makeVar, useReactiveVar

    } from "@apollo/client" ; const hogeItemVar = makeVar("hoge"); export const HogeComponent = () => { const hogeItem = useReactiveVar (hogeItemVar); // 即反映 // ... } export const FugaComponent = () => { useEffect(() => { hogeItemVar("fuga"); // fugaに更新 }, []) // ... } シンプルな構文
  7. 気になる点 - 学習コスト - プロダクトが⼤きくなるにつれてキャッシュを把握しづらくなる - 多重リクエストが送られるバグが発⽣し負荷増加した例も - プロダクトの特性 +

    ライブラリの機能を理解した上で実装 - 新しいReactへの順応が⽐較的遅い - 最近はSuspenseに対応したりFragment Colocationにも⼀部対応 8 他ライブラリの調査を開始
  8. 調査対象 9 - URQL - Relay - graphql-request - Redux

    Toolkit - Recoil - Jotai GraphQL Client 状態管理ライブラリ
  9. 重視する基準 - GraphQL Client 1. 機能⾯ - キャッシュ機構 - ⾃動型⽣成

    2. コスト⾯ - 学習コスト - 移⾏コスト - すぐに移⾏するわけではないが⼀応調査 10
  10. URQL - 🟢 キャッシュ機構 - Document Caching (無期限に保存) - 拡張で正規化キャッシュも使⽤可能

    - 🟢 ⾃動型⽣成 - GraphQL Code Generator - 🟡 学習コスト - 新しいキャッシュ機構の学習が必要 - 🟢 移⾏コスト - ⾃動型⽣成ツールがApollo Clientと同じ 11 🟢: よさそう 🟡: なんとかなりそう 🔴: たいへんそう
  11. URQL - Document Caching 12 hash(query+variables) を キーにして結果をキャッシュ query GetPerson($id:

    ID!) { person(id: $id) { __typename // “Person” id name } } { __typename: "Person", id: "hogehoge", name: "shikachii", } mutation DeletePerson($id: ID!) { deletePerson(id: $id) { __typename // “Person” id // “fugafuga” } } 同じ__typenameのキャッシュを破棄💥 { __typename: "Person", id: "fugafuga", } hash(stringify(query) + stringify({ id: "hogehoge" }))
  12. Relay - 🟢 キャッシュ機構 - 正規化キャッシュ - キャッシュのGC - 🟢

    ⾃動型⽣成 - Relay Compiler - 🟡 学習コスト - Fragment Colocation - 🔴 移⾏コスト - コンポーネント単位でのデータフェッチ 13
  13. graphql-request + (SWR or Tanstack Query) - 🟢 キャッシュ機構 -

    SWRやTanstack Queryとの併⽤ - 🟢 ⾃動型⽣成 - GraphQL Code Generator - 🟡 学習コスト - SWR, Tanstack Query - 🟡 移⾏コスト - 既存のデータフェッチ部分の検証が必要 14
  14. ⽐較 - GraphQL Client - 主観 + 定性的に⽐較 15 ※各ライブラリの良し悪しではありません

    キャッシュ機構 自動型生成 学習コスト 移行コスト Apollo Client 🟢 🟢 🟡 N/A URQL 🟢 🟢 🟡 🟢 Relay 🟢 🟢 🟡 🔴 graphql-request 🔴 🟢 🟢 🟢 + SWR or TanstackQuery 🟢 🟢 🟡 🟡
  15. 重視する基準 - 状態管理ライブラリ 1. 機能⾯ - 構⽂のシンプルさ - 無駄な再レンダリングが発⽣しない 2.

    コスト⾯ - 学習コスト - 移⾏コスト - 構⽂がシンプルなら低いので省略 16
  16. Redux Toolkit - 🔴 構⽂のシンプルさ - アーキテクチャがしっかりしている分複雑 - Zustandではシンプルに書くことはできる -

    🔴 学習コスト - プロダクト特性を理解した上でFluxアーキテクチャの適⽤ 17 Action Dispatcher Store View Action
  17. Recoil - 🟡 構⽂のシンプルさ - atomを使うだけであればかなりシンプル - ⼀意のkeyを指定しないといけない - 🟢

    学習コスト - useStateと同じような感覚で利⽤可能 18 Selector Atom “shikachii” Selector Atom+”san” import { atom, useRecoilState } from "recoil"; const hogeItemAtom = atom({ key: 'hogeItem', default: 'hoge' }) export const HogeComponent = () => { const [hogeItem, setHogeItem] = useRecoilState (hogeItemAtom); // ... }
  18. Jotai - 🟢 構⽂のシンプルさ - Recoilで必要だった⼀意のkey管理が不要 - 🟢 学習コスト -

    Recoil, useStateと同じような感覚で利⽤可能 19 import { makeVar, useReactiveVar } from "@apollo/client"; const valueVar = makeVar(0); export const HogeComponent = () => { const value = useReactiveVar(valueVar); valueVar(value + 1); // ... } import { atom, useAtom } from 'jotai'; const valueAtom = atom(0); export const HogeComponent = () => { const [value, setValue] = useAtom(valueAtom); setValue(value + 1); // ... }
  19. ⽐較 - 状態管理ライブラリ - 主観 + 定性的に⽐較 20 シンプルさ 学習コスト

    Apollo Client 🟢 N/A Redux Toolkit 🔴 🔴 Recoil 🟡 🟢 Jotai 🟢 🟢
  20. 調査結果をふまえて - DMM TVはコンテンツ配信型のアプリケーション - Mutation < Query - Document

    Cachingを活かせる → URQLよさそう - 現状複雑な状態管理をしていない - Jotaiの機能があれば必要⼗分 21 他ライブラリの調査を通じてプロダクトに対する解像度が向上
  21. まとめ 22 1. DMM TV WebブラウザチームではApollo Clientを使⽤ 2. 気になる点がいくつかあり他ライブラリを調査 3.

    コンテンツ配信型であればURQL+Jotaiがよさそう 4. Apollo Clientの客観的理解 + ⾃⼰成⻑
  22. Fragment Colocation - ウォーターフォール問題の改善 - 親で全てのデータを取得 - 関⼼の分離 - コンポーネントが使う値のみ考慮

    25 query UserPage($id: ID!) { person(id: $id) { id name company { id name } } } fragment Company on Company { id name } query UserPage($id: ID!) { person(id: $id) { id name company { ...Company } } }