意外と難しいGraphQLのスカラー型
by
uhyo
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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