意外と難しいGraphQLのスカラー型
by
uhyo
×
Copy
Open
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
意外と難しいGraphQLのスカラー型 2025-09-22『TypeScriptのスキーマ駆動開発』実践事例 LT
Slide 2
Slide 2 text
発表者紹介 uhyo 株式会社カオナビ フロントエンドエキスパート 前職ではGraphQLを使っていた。 2
Slide 3
Slide 3 text
注意 この話は、GraphQL + TypeScriptの定番ツール GraphQL Codegen よりも安全性にこだわった自作ツール nitrogql が流行らないことの恨み節です。 3
Slide 4
Slide 4 text
GraphQLとTypeScriptの型の関係 GraphQLには、型の概念が存在する。 String, Int, Boolean 型など。 TypeScriptのコード生成をする場合、GraphQLの型を TypeScriptの型に対応付ける必要がある。 例: String→string Int→number 4 GraphQLの型 TypeScriptの型
Slide 5
Slide 5 text
注意が必要なID型 ID型もGraphQLに組み込みの型だが、 特殊な性質を持つ。 •文字列としてシリアライズされる。 •しかし、ID型の入力としては整数も受け付ける。 5
Slide 6
Slide 6 text
注意が必要なID型 ID → string ? ID → string | number ? 6
Slide 7
Slide 7 text
注意が必要なID型 const data = useQuery({ query, variables: { inputId: 12345 }, }); data.outputId 7 このIDは string | number になるのが望ましい (シリアライズ前のため) このIDは string になるのが望 ましい (シリアライズ済のため)
Slide 8
Slide 8 text
GraphQL Codegenでは…… 状況に応じてID型に対応するTypeScriptの型を 出し分ける必要がある。 ところが、GraphQL Codegenは一律で string型を出力。(デフォルトの設定の場合) 本来numberが使えるはずの場面で使わせて くれない! 8
Slide 9
Slide 9 text
設定を変えればいける こんな設定を書けばGraphQL Codegenでも 出し分けが可能。 scalars: { ID: { input: ‘string | number’, output: ‘string’ } } 9
Slide 10
Slide 10 text
GraphQL Codegenでの出し分け const data = useQuery({ query, variables: { inputId: 12345 }, }); data.outputId 10 ここではinput用の型を使用 (string | number) ここではoutput用の型を使用 (string)
Slide 11
Slide 11 text
めでたし……と思いきや サーバー側(GraphQLのリゾルバー定義) 向けの型もGraphQL Codegenで出力すると…… deleteUser: (_, { id }) => { return userStore.delete(id); } 11
Slide 12
Slide 12 text
めでたし……と思いきや サーバー側(GraphQLのリゾルバー定義) 向けの型もGraphQL Codegenで出力すると…… deleteUser: (_, { id }) => { return userStore.delete(id); } 12 入力なのでinput用の型が使用 されるが、正しい型はstring (string | numberではない!) ※逆に、resolverの実装から出力されるIDは string | number型が正しい
Slide 13
Slide 13 text
GraphQL Codegen向けの正しい設定 こうする必要がある。 どうしてこうなった…… scalars: { //クライアント用 ID: { input: ‘string | number’, output: ‘string’ } } 13 scalars: { //サーバー用 ID: { input: ‘string’, output: ‘string | number’ } }
Slide 14
Slide 14 text
一方nitrogqlでは input/outputではなくsend/receiveという分けを 導入することで、両者で共通の定義にできる。 scalarTypes: { //クライアント・サーバー共通 ID: { send: ‘string | number’, receive: ‘string’ } } 14
Slide 15
Slide 15 text
まとめ GraphQL CodegenはGraphQL + TypeScript向け のデファクトスタンダードなツールだが、 型安全に使うために適切に設定する難易度が とても高い。気を付けよう。 15