LoginSignup
2
1

More than 1 year has passed since last update.

Apollo Clientで始めるGraphQLと状態管理

Last updated at Posted at 2022-09-13
1 / 35

GraphQLとそのクライアントライブラリ「Apollo Client」の話です


GraphQLで開発を行っているチームに向けた社内勉強会用の資料です。

コードはボイラープレート化されていますが、GraphQLのメリットや全体像について理解を促進する目的で作成しました。


Topic 💁

・GraphQLの特徴
・Apollo Client
・GraphQL Code Generator
・開発の流れ


GraphQLの特徴


GraphQLの特徴 - Schema

APIとクライアント間のインターフェースとして利用される

type Post {
  id: String!
  created_at: DateTime!
}

GraphQLの特徴 - Schema

クライアントからは
・request / responseの型情報
・データ取得関数の自動生成
として利用される。


GraphQLの特徴 - Schema

・補完が効いて開発効率が上がる ✅
・型安全になり修正・リファクタ時の負荷が軽減される ✅

e.g. API変更の影響をざっくり知りたい

$ npm run lint:ts

GraphQLの特徴 - RESTとの比較

・クライアントがレスポンスを組み立てる
・基本的にリソース=リゾルバ (エンドポイント単位でのサブリソースの管理が不要)

e.g. 記事ページのAPIにコメントを生やしたが、他ページでもコメントを取りたくなった


GraphQLの特徴 - RESTとの比較

・クライアントファーストな仕組みと言える
・クライアントに複雑性が移動してきた背景を考えるとGraphQLの登場は自然な文脈
・学習・環境構築コストが高く、パフォーマンス出しにくいため使い所は見極めたい


Apollo Client


Apollo Client

・クライアント側のGraphQLライブラリ
・旧facebook社が開発したRelayと2大巨頭
・後発ながら機能が豊富で利用者が多く、Relayに比べて制約が弱め


Apollo Client - 状態管理

コンポーネントを跨いで利用したい状態をグローバルステートと呼び、その管理方法が「状態管理」と呼ばれている

状態管理で扱うデータの種類は大きく2つ
・API経由データ
・それ以外データ (共通モーダルの表示など)


Apollo Client - 状態管理

Reduxなどを利用してコンポーネントを跨いで利用したいグローバルステートを管理するのがセオリー化している

下記のような課題がある (と感じている)
・ボイラープレートが多くて大変
・コード量が多くなると職人が必要


Apollo Client - 状態管理

SWR, useQueryといったキャッシュ機構を持つライブラリが流行ってきた

前述の「API経由、それ以外データ」を識別子単位でメモリキャッシュしてくれる機能を持っている


Apollo Client - 状態管理

apolloもキャッシュ機構を持っていて、更にオブジェクトごとに正規化してくれる機能がついている

// __typename x idを識別子としてユニーク性を担保
{ __typename: 'Post', id: 'uuid-1', name: 'something' },
{ __typename: 'Post', id: 'uuid-2', name: 'anything' }

Apollo Client - 状態管理

下記のような挙動が可能
・ミューテーションで記事を更新する
・記事一覧のキャッシュが更新される
・記事一覧の表示が更新される

-> API経由データの更新時にグローバルステートの更新が不要になる 👏


Apollo Client - 状態管理

それ以外データは「Reactive variables」という機能を利用して、従来通り自分で変更します。


Apollo Client - 状態管理

// store.js
const flagVar = makeVar(false);

// component.jsx
const Component = () => {
  const flag = useReactiveVar(flagVar); // reactiveに変更を検知
  return <div onClick={() => flagVar(true)}>{flag}</div>;
}

GraphQL Code Generator


GraphQL Code Generator

下記を自動生成してくれるツール
・APIのレスポンス型
・データ取得のhooks


GraphQL Code Generator

このとき自動生成されるコードは下記を参照している
・Schema
・オペレーションコード (クライアントからのリクエスト)


GraphQL Code Generator - query(参照)

Schema

// ルート型
type Query {
  post: Post // フィールド(RESTのendpointに相当)
}
// オブジェクト型
type Post { id: String! title: String }

GraphQL Code Generator - query(参照)

オペレーションコード

query PostPage { // オペレーションタイプ オペレーションネーム
  post { // フィールド
    id
    title
  }
}

GraphQL Code Generator - query(参照)

生成されるコード (抜粋)

type PostPageQuery = { // レスポンス型
  __typename: 'Post';
  id: string;
  title: string | null | undefined;
};
const usePostPageQuery = useQuery(...); // hooks

GraphQL Code Generator - query(参照)

hooksの使い方

const Component = () => {
  const { data, loading, error } = usePostPageQuery();
  if (error) return throw error; // エラー
  if (loading) return <div>Loading</div>; // ローディング中
  return <div>{`${data.post.id}: ${data.post?.title}`}</div>;
};

GraphQL Code Generator - mutation(更新)

Schema

type Mutation {
  update_post(input: UpdatePostInput!): UpdatePostMutation!
}
type UpdatePostInput { id: String! title: String! } // パラメータ
type UpdatePostMutation { post: Post } // レスポンス

GraphQL Code Generator - mutation(更新)

オペレーションコード

mutation PostPageUpdate($input: UpdatePostInput!) {
  update_post(input: $input) {
    id // ここからレスポンス
    title
  }
}

GraphQL Code Generator - mutation(更新)

生成されるコード (抜粋)

type PostPageUpdateMutation = { // レスポンス型
  __typename: 'PostPageUpdateMutation';
  post: Post;
};
const usePostPageUpdateMutatiion = useMutation(...); // hooks

GraphQL Code Generator - mutation(更新)

hooksの使い方

const Component = () => {
  const [mutate] = usePostPageUpdateMutatiion(); // 関数取得
  const handleUpdate = async () => {
    const { error } = await mutate();
    if (error) return throw error; // エラー
  };
  return <button onClick={handleUpdate}></button>;
};

開発の流れ


開発の流れ

GraphQLでの開発方法は主に2種類
・Code First
型・リゾルバーからスキーマ生成 (我々はこちら)
・Schema First
スキーマからコード生成 (gqlgenなど)


開発の流れ

[BE] テーブル設計
[ALL] ER図とデザイン見てスキーマ相談
[BE] リソースの型とリゾルバー(ロジック)書く
[BE] スキーマ自動生成
[FE] オペレーション書く
[FE] レスポンス型・hooks自動生成


開発の流れ - 課題

このチームはBE/FEが別れており、コードファーストのためスキーマを相談するタイミングが見失われがちです。
デザイン・ER図ができたタイミングで、スキーマを相談するタイミングがあるとスムーズに実装を進められます<(__*)> :pray:


最後に

kibelaにドキュメントを作成しています 💁
よく使う用語やライブラリのAPIを記載していますので、困ったときにご覧ください。

・GraphQLの用語集
・[FE] ApolloClientの使い方

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1