GraphQLで存在しないエントリーポイントを指定していると誤解した小ネタ
始めに
小ネタです。
弊社システムではGraphQLを採用していますが、存在しないmutationを指定していると勘違いしたものを残しておきます。
環境
なし。
実装
次のようなクエリがありました。
mutation createUser($input: CreateUserInput!) {
createUserWithRole(input: $input) {
}
}
私はcreateUser
というサーバのmutationエントリーポイントを実行していると判断していました。しかし、実際にはcreateUserWithRole
を実行しています。このcreateUser
はクライアントがどのような実行単位なのかをまとめるためのラベルであり、サーバには関係がありません。ちなみにこのcreateUser
のことをoperation
名と表現します。
基本的にはクライアントのoperation
名とサーバのmutationエントリーポイント名は一致させているコードが多数だったので誤解していました。また、さらに付け加えると私と同じくGraphQLの仕様を正確に知らなかった過去のソースもあり、同じ処理内容なのに別で定義されていたGQLがあったため、混乱を招く結果となりました。
# 呼び出し方が違うだけで中身は同じ。キャッシュされたくないとか、なにか理由があったのかも・・・?
mutation createUser($input: CreateUserInput!) {
createUserWithRole(input: $input) {
}
}
mutation createUserWithRole($input: CreateUserInput!) {
createUserWithRole(input: $input) {
}
}
本来なら複数のエントリーポイントを実行する処理を一つのoperation
として定義できるので、流用性が高まる良い機能なのですがGraphQLを詳しく知ろうとしなかったので調査にハマる結果となってしまいました。
mutation updateTwoUsers {
user1: updateUser(id: "1", input: { name: "Alice" }) { id name }
user2: updateUser(id: "2", input: { name: "Bob" }) { id name }
}
ソースコード
なし。
終わりに
今回ハマったことにより、GraphQLで一気に複数のエントリーポイントに処理を投げられるということを今回改めて知りました。同じことをREST APIで実行しようとしても、それぞれが独立しているから、RxJSでforkjoin等で処理を集約しなければならないのは結構大変ですね。
GraphQLはどちらかというとフロントに応じた複数リソースの参照のためだけに必要だと認識していたので、更新も一気にできることを知れてよかったです。
とはいえ、ハンドリングが複雑になりそうなので特別なユースケースがない限りはやらないと思います。
Discussion