Open4
GraphQL クライアントの比較
GraphQL 専用クライアント
- Apollo Client
- Relay
- Urql
データフェッチングライブラリ + ミニマルなクライアント
-
React-query
-
SWR
-
graphql-request
ほしいもの
- useFetch 系の関数
- const { data, error, loading } = useHogeQuery()
- 上記関数がスキーマから graphql-codegen で生成できる
- キャッシュがいい感じにできる
- ここが違いが最も現れる部分そうなので、具体化して検討する
- SSG, SSR で動く
キャッシュについて
正規化されたキャッシュが必要なのか
この記事を読んで本当に正規化されたキャッシュが必要なのかを考えてみた方がいいなと思った
正規化の目的
キャッシュされたデータを使いつつ最新の状態を保つため
例えば「記事の一覧」をあるページで取得して、他のページでその記事にいいね!を実行した場合、一覧を取得したページに戻ったときに一覧のデータを再取得せずとも「いいね!をした」という状態はアップデートされていて欲しい、といった感じ。
正規化するために何が必要なのか
Apollo では id + __typename で unique な ID が作られ正規化されている
Splitting the results into individual objects
Assigning a logically unique identifier to each object so that the cache can keep track of the entity in a stable way
Storing the objects in a flattened data structure (normalized items)
mutation を起こした時に結果をの値を返すようにする
手動で update 関数を書く
function AddTodo() {
let input;
const [addTodo] = useMutation(ADD_TODO, {
update(cache, { data: { addTodo } }) {
cache.modify({
fields: {
todos(existingTodos = []) {
const newTodoRef = cache.writeFragment({
data: addTodo,
fragment: gql`
fragment NewTodo on Todo {
id
type
}
`
});
return [...existingTodos, newTodoRef];
}
}
});
}
});
正規化しない場合はどうするか
一つ解決策としてあるのが毎回再取得するということ。
これでパフォーマンスの問題が大して大きくならなければこれでいい気がする。
Apollo なら refetchQueries を指定する。
Urql なら設定なしでやってくれるっぽい。
urql による比較