--- id: wiki-2026-0508-graphql-code-generator title: GraphQL Code Generator category: 10_Wiki/Topics status: verified canonical_id: self aliases: [graphql-codegen, GQL Codegen, Type-safe GraphQL] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [graphql, typescript, codegen, type-safety] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: graphql --- # GraphQL Code Generator ## 매 한 줄 > **"매 schema → typed client 의 자동화"**. `.graphql` schema + operation 으로부터 TypeScript types, hook, fragment 의 생성. 매 schema drift 의 compile-time 차단 — `any` 의 X, `User.email` typo 의 즉시 error. ## 매 핵심 ### 매 핵심 plugin - **typescript**: schema → TS types (scalar, enum, input, object). - **typescript-operations**: query/mutation operation → typed result. - **typed-document-node**: TypedDocumentNode (apollo-client / urql 의 input). - **client-preset** (modern, 2026 default): 매 fragment-masking, persisted-query 의 통합 preset. ### 매 fragment masking - Component A 가 fragment X 정의 → component B 가 fragment X 의 field 접근 시 compile error. - 매 over-fetching 의 prevention 강제. ### 매 응용 1. React + Apollo / urql 매 typed hook 자동 생성. 2. Backend schema change 시 client compile error 즉시 감지. 3. Persisted queries (production safety, query whitelisting). ## 💻 패턴 ### codegen.ts (client-preset) ```typescript import { CodegenConfig } from '@graphql-codegen/cli'; const config: CodegenConfig = { schema: 'https://api.example.com/graphql', documents: ['src/**/*.{ts,tsx}', '!src/gql/**/*'], generates: { './src/gql/': { preset: 'client', presetConfig: { fragmentMasking: { unmaskFunctionName: 'getFragmentData' }, }, config: { useTypeImports: true, scalars: { DateTime: 'string', UUID: 'string' }, }, }, }, hooks: { afterAllFileWrite: ['prettier --write'] }, }; export default config; ``` ```bash pnpm graphql-codegen --watch ``` ### Operation — typed result ```typescript // src/components/UserCard.tsx import { graphql } from '../gql'; import { useQuery } from '@apollo/client'; const USER_QUERY = graphql(` query GetUser($id: ID!) { user(id: $id) { id name email avatarUrl } } `); export function UserCard({ id }: { id: string }) { const { data } = useQuery(USER_QUERY, { variables: { id } }); // 매 data?.user 의 type 의 fully inferred return
{data?.user?.name}
; } ``` ### Fragment masking ```typescript const USER_AVATAR_FRAGMENT = graphql(` fragment UserAvatar on User { avatarUrl name } `); function Avatar({ user }: { user: FragmentType }) { const u = getFragmentData(USER_AVATAR_FRAGMENT, user); return {u.name}; } // parent — 매 user 의 email 의 access X (fragment 의 declare X) function Parent({ user }) { return ; // user.email 의 access 시 TS error } ``` ### Persisted queries ```typescript { generates: { './persisted-operations.json': { preset: 'client', presetConfig: { persistedDocuments: true }, }, }, } ``` ```typescript // runtime — query string 의 X, hash 만 전송 import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries'; const link = createPersistedQueryLink({ generateHash: doc => doc['__meta__']['hash'] }); ``` ### Custom scalar mapping ```typescript config: { scalars: { DateTime: 'string', // ISO 8601 JSON: 'Record', BigInt: 'string', }, } ``` ### Watch + CI ```json { "scripts": { "codegen": "graphql-codegen", "codegen:watch": "graphql-codegen --watch", "ci:codegen-check": "graphql-codegen && git diff --exit-code src/gql/" } } ``` ### Multi-schema (federation) ```typescript { schema: ['./schema/users.graphql', './schema/products.graphql'], // 매 federated graph 의 single typed client } ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | 새 React + GraphQL | client-preset + fragment masking | | Apollo Client (legacy) | typescript + typescript-react-apollo | | urql | client-preset (urql 의 native 지원) | | Production 보안 | persisted queries 의 enable | | Backend schema 의 evolve | CI 의 codegen drift check | **기본값**: client-preset + fragmentMasking, CI 의 codegen drift check. ## 🔗 Graph - 부모: [[GraphQL]] · [[TypeScript]] - 변형: [[urql]] · [[Apollo-Client]] · [[Relay]] - 응용: [[Type-Safe-API-Client]] · [[Persisted-Queries]] - Adjacent: [[OpenAPI-Codegen]] · [[tRPC]] ## 🤖 LLM 활용 **언제**: GraphQL schema 가 있는 TS project, multi-team 의 schema drift 방지, persisted query 도입. **언제 X**: REST-only, 매 GraphQL schema 의 unstable 한 prototype phase. ## ❌ 안티패턴 - **codegen output 의 manual edit**: 매 next run 시 overwrite, 매 변경 의 lost. - **fragment 의 component 외 정의**: fragment masking 의 weak — co-location 강제. - **DateTime 의 `Date` mapping**: GraphQL response 는 string, 매 runtime mismatch 유발. - **CI 에 codegen drift check 의 X**: schema 의 silent breakage. ## 🧪 검증 / 중복 - Verified (graphql-code-generator.com docs, client-preset migration guide). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — GraphQL Codegen client-preset 패턴 정리 |