クライアントサイドにおけるGraphQLクエリ管理
クライアントで GraphQL クエリをどのように管理すべきか
TL;DR
クライアントサイドで GraphQL クエリを扱いたい場合、文字列等を操作して、あるいはクエリビルダのようなものを利用して動的にクエリを生成するのではなく、静的なクエリ定義を保持しておき利用するのが良いとされているようだ。
そもそも、GraphQL には変数が仕様として盛り込まれているし、普通 GraphQL サーバーはそれを扱えるようになっている。なので、可変な値についてクエリを投げたい場合は、下記のように変数を扱うのが良いらしい。
code:typescript
import gql from "graphql-tag";
const query = gql`
query getUserById {
user(id: $id) {
id
}
}
`;
const variables = {
id: 1
}
// 例えば、Apollo Client なら以下のようにクエリを投げられる
client.query({ query, variables });
なぜ動的にクエリを利用するのはよくないのか
以下のような話がある。
GraphQL クエリを文字列として扱って動的に生成する等した場合、主に、以下のようなメリットがあるとのことだ。
GraphQL クエリ用の拡張は、クエリを文字列として扱った場合よりも、静的なクエリを扱った方が高機能なものがある
静的なクエリとして扱うことで、拡張機能がハイライトや補完を行うだけでなく、静的解析も行うことができる
型のコード生成が利用できる
GraphQL クエリからネイティブコードを生成するツールはたくさんある。元々 GraphQL クエリはモバイル端末が普及したことでより通信量を削減する必要が出てきた、みたいなのが出現の背景の1つとしてあるからか、クライアントサイドのコード生成をするためのツールが色々あるっぽい
動的にクエリを生成してしまうと、こういったコードジェネレータの恩恵が受けられなくなってしまう
サーバーサイドでロギングする際にクエリの operation 名が活用できる
GraphQL では各クエリ自体に名前をつけることができるので、これを利用するとサーバサイドでログを活用する際に便利。例えば、以下は HeroNameAndFriends という名前のクエリになる
code:javascript
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
OSS の GraphQL クライアント (Relay 1, Lokka) には動的にクエリを生成するものがあったりするが、その場合このクエリの名前も動的に生成されてしまい利点をいかせないということがあるようだ