From b3b489fb3117e3b37d0da72162c0ee7161d8e880 Mon Sep 17 00:00:00 2001 From: sarahxsanders Date: Tue, 22 Apr 2025 19:18:15 -0400 Subject: [PATCH 01/11] add guide for graphQL server type generation --- website/pages/docs/_meta.ts | 5 + website/pages/docs/type-generation.mdx | 201 +++++++++++++++++++++++++ 2 files changed, 206 insertions(+) create mode 100644 website/pages/docs/type-generation.mdx diff --git a/website/pages/docs/_meta.ts b/website/pages/docs/_meta.ts index 39ac3a1486..14f720b553 100644 --- a/website/pages/docs/_meta.ts +++ b/website/pages/docs/_meta.ts @@ -19,7 +19,12 @@ const meta = { 'constructing-types': '', 'oneof-input-objects': '', 'defer-stream': '', + 'type-generation': '', '-- 3': { + type: 'separator', + title: 'Testing', + }, + '-- 4': { type: 'separator', title: 'FAQ', }, diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx new file mode 100644 index 0000000000..865d30915a --- /dev/null +++ b/website/pages/docs/type-generation.mdx @@ -0,0 +1,201 @@ +--- +title: Type Generation for GraphQL Servers +sidebarTitle: Type Generation +--- + +# Type Generation for GraphQL Servers + +Writing a GraphQL server in JavaScript or TypeScript often involves managing complex +types. As your API grows, keeping these types accurate and aligned with your schema +becomes increasingly difficult. + +Type generation tools automate this process. Instead of manually defining or maintaining +TypeScript types for your schema and operations, these tools can generate them for you. +This improves safety, reduces bugs, and makes development easier to scale. + +This guide walks through common type generation workflows for projects using +`graphql-js`, including when and how to use them effectively. + +## Why use type generation? + +Type generation improves reliability and developer experience across the development +lifecycle. It's especially valuable when: + +- You want strong type safety across your server logic +- Your schema is defined separately in SDL files +- Your API surface is large, rapidly evolving, or used by multiple teams +- You rely on TypeScript for editor tooling, autocomplete, or static analysis + +By generating types directly from your schema, you can avoid drift between schema +definitions and implementation logic. + +## Code-first development + +In a code-first workflow, the schema is constructed entirely in JavaScript or TypeScript +using `graphql-js` constructors like `GraphQLObjectType`, `GraphQLSchema`, and others. +This approach is flexible and lets you build your schema programmatically using native +language features. + +If you're using this approach with TypeScript, you already get some built-in type safety +with the types exposed by `graphql-js`. For example, TypeScript can help ensure your resolver +functions return values that match their expected shapes. + +However, code-first development has tradeoffs: + +- You won't get automatic type definitions for your resolvers unless you generate +them manually or infer them through wrappers. +- Schema documentation, testing, and tool compatibility may require you to export +the schema to SDL first. + +You can still use type generation tools like GraphQL Code Generator in a code-first setup. +You just need to convert your schema into SDL. + +To export your schema: + +```ts +import { printSchema } from 'graphql'; +import { schema } from './schema'; +import { writeFileSync } from 'fs'; + +writeFileSync('./schema.graphql', printSchema(schema)); +``` + +Once you've written the SDL, you can treat the project like a schema-first project +for type generation. + +## Schema-first development + +In a schema-first workflow, your GraphQL schema is written in SDL, for example, `.graphql` +or `.gql` files. This serves as the source of truth for your server. This approach +emphasizes clarity because your schema is defined independently from your business logic. + +Schema-first development pairs well with type generation because the schema is +serializable and can be directly used by tools like GraphQL Code Generator. + +With a schema-first workflow, you can: + +- Generate resolver type definitions that match your schema +- Generate operation types for client queries, integration tests, or internal tooling +- Detect breaking changes and unused types through schema diffing tools + +## Generating resolver types + +GraphQL Code Generator can generate resolver scaffolding based on your schema. These +types help you implement resolvers with full type safety, including parent types, +argument shapes, return values, and context. + +Example `codegen.ts` config: + +```ts +import type { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: './schema.graphql', + generates: { + './src/generated/resolvers-types.ts': { + plugins: ['typescript', 'typescript-resolvers'], + }, + }, +}; +export default config; +``` + +To run the generator: + +```bash +npx graphql-codegen +``` + +This creates a set of resolver types like: + +```ts +export type QueryResolvers = { + user?: Resolver>; +}; +``` + +These types ensure that the `user` resolver expects an `id` argument and returns a +`User`, giving you confidence and autocomplete while implementing your server logic. + +## Using generated types in your server + +Once generated, you can use these types directly in your resolver map: + +```ts +import { QueryResolvers } from './generated/resolvers-types'; + +export const queryResolvers: QueryResolvers = { + user: (parent, args, context) => { + return context.db.getUser(args.id); + }, +}; +``` + +You can also extract shared `ContextType` and `Resolver` +utility types from the generated file and apply them across your codebase. + +## Generating operation types + +In addition to resolver types, you can generate types for GraphQL operations such +as queries, mutations, and fragments. This is especially useful for shared integration tests +or client logic that needs to match the schema precisely. + +Suppose you have a query in `./src/operations/getUser.graphql`: + +```graphql +query GetUser($id: ID!) { + user(id: $id) { + id + name + } +} +``` + +Update your codegen config: + +```ts +const config = { + schema: './schema.graphql', + documents: './src/operations/**/*.graphql', + generates: { + './src/generated/operations.ts': { + plugins: ['typescript', 'typescript-operations'], + }, + }, +}; +``` + +This produces types like `GetUserQuery` and `GetUserQueryVariables`, which you can +import into your client code or test files. + +## Typing resolvers manually + +If you aren't ready to introduce type generation, you can still get partial type safety +using `graphql-js` built-in types. + +```ts +import { GraphQLFieldResolver } from 'graphql'; + +const myResolver: GraphQLFieldResolver = ( + parent, + args, + context, + info +) => { + // ... +}; +``` + +This pattern may be enough for small projects or static schemas, but it +can be hard to maintain and scale without automation. + +## Best practices for CI and maintenance + +To keep your type generation reliable and consistent: + +- Check in generated files to version control so teammates and CI systems don't produce +divergent results. +- Run type generation in CI to ensure types stay in sync with schema changes. +- Use schema diffing tools like `graphql-inspector` to catch breaking changes before +they're merged. +- Automate regeneration with pre-commit hooks, GitHub Actions, or lint-staged workflows. \ No newline at end of file From e157546572cb7c6885d225af64f905e876548459 Mon Sep 17 00:00:00 2001 From: sarahxsanders Date: Sat, 26 Apr 2025 16:05:30 -0400 Subject: [PATCH 02/11] feedback --- website/pages/docs/type-generation.mdx | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index 865d30915a..2170d60fb8 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -1,9 +1,9 @@ --- -title: Type Generation for GraphQL Servers +title: Type Generation for GraphQL sidebarTitle: Type Generation --- -# Type Generation for GraphQL Servers +# Type Generation for GraphQL Writing a GraphQL server in JavaScript or TypeScript often involves managing complex types. As your API grows, keeping these types accurate and aligned with your schema @@ -70,7 +70,7 @@ or `.gql` files. This serves as the source of truth for your server. This approa emphasizes clarity because your schema is defined independently from your business logic. Schema-first development pairs well with type generation because the schema is -serializable and can be directly used by tools like GraphQL Code Generator. +serializable and can be directly used by tools like [GraphQL Code Generator](https://the-guild.dev/graphql/codegen). With a schema-first workflow, you can: @@ -80,9 +80,9 @@ With a schema-first workflow, you can: ## Generating resolver types -GraphQL Code Generator can generate resolver scaffolding based on your schema. These -types help you implement resolvers with full type safety, including parent types, -argument shapes, return values, and context. +We recommend using the [GraphQL Code Generator Server Preset](https://the-guild.dev/graphql/codegen/docs/guides/graphql-server-apollo-yoga-with-server-preset) +to generate resolver types. It automatically generates resolver types based on your schema, including parent types, +arguments, return values, and context, without needing extra plugin setup. Example `codegen.ts` config: @@ -140,6 +140,10 @@ In addition to resolver types, you can generate types for GraphQL operations suc as queries, mutations, and fragments. This is especially useful for shared integration tests or client logic that needs to match the schema precisely. +We recommend using the GraphQL Code Generator Server Preset for generating operation types. +The server preset generates both resolver and operation types, without needing to install +or configure additional plugins. + Suppose you have a query in `./src/operations/getUser.graphql`: ```graphql @@ -154,15 +158,18 @@ query GetUser($id: ID!) { Update your codegen config: ```ts -const config = { +import type { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { schema: './schema.graphql', documents: './src/operations/**/*.graphql', generates: { - './src/generated/operations.ts': { - plugins: ['typescript', 'typescript-operations'], + './src/generated/': { + preset: 'graphql-codegen-preset-server', }, }, }; +export default config; ``` This produces types like `GetUserQuery` and `GetUserQueryVariables`, which you can From d0cdf3a8a2c1db0c2829d001ceac1aa1197a0254 Mon Sep 17 00:00:00 2001 From: sarahxsanders Date: Tue, 13 May 2025 19:51:28 -0400 Subject: [PATCH 03/11] fix spellcheck --- cspell.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.yml b/cspell.yml index fb16fb4497..3032bd2c86 100644 --- a/cspell.yml +++ b/cspell.yml @@ -25,6 +25,7 @@ overrides: - swcrc - noreferrer - xlink + - codegen ignoreRegExpList: - u\{[0-9a-f]{1,8}\} From a2175c393d66b25c5ddb08b38adb1a7bd37b252c Mon Sep 17 00:00:00 2001 From: sarahxsanders Date: Fri, 16 May 2025 16:27:58 -0400 Subject: [PATCH 04/11] feedback from Eddy --- website/pages/docs/type-generation.mdx | 174 +++++++++++++++---------- 1 file changed, 107 insertions(+), 67 deletions(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index 2170d60fb8..fb92493d1b 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -74,127 +74,167 @@ serializable and can be directly used by tools like [GraphQL Code Generator](htt With a schema-first workflow, you can: -- Generate resolver type definitions that match your schema +- Generate resolver type definitions and files that match your schema - Generate operation types for client queries, integration tests, or internal tooling - Detect breaking changes and unused types through schema diffing tools ## Generating resolver types -We recommend using the [GraphQL Code Generator Server Preset](https://the-guild.dev/graphql/codegen/docs/guides/graphql-server-apollo-yoga-with-server-preset) -to generate resolver types. It automatically generates resolver types based on your schema, including parent types, -arguments, return values, and context, without needing extra plugin setup. +We recommend using the [Server Preset](https://www.npmjs.com/package/@eddeee888/gcg-typescript-resolver-files) for a +managed workflow. It automatically generates types and files based on your schema without needing extra plugin setup. -Example `codegen.ts` config: +The Server Preset generates: -```ts -import type { CodegenConfig } from '@graphql-codegen/cli'; +- Resolver types, including parent types, arguments, return values, and context +- Resolver files with types wired up, ready for your business logic +- A resolver map and type definitions to plug into GraphQL servers + +This setup expects your schema is split into modules to improve readability and maintainability. For example: + +```pgsql +├── src/ +│ ├── schema/ +│ │ ├── base/ +│ │ │ ├── schema.graphql +│ │ ├── user/ +│ │ │ ├── schema.graphql +│ │ ├── book/ +│ │ │ ├── schema.graphql +``` + +Here's an example `codegen.ts` file using the Server Preset: + +```ts filename="codegen.ts" +import type { CodegenConfig } from "@graphql-codegen/cli"; +import { defineConfig } from "@eddeee888/gcg-typescript-resolver-files"; const config: CodegenConfig = { - schema: './schema.graphql', + schema: "src/**/schema.graphql", generates: { - './src/generated/resolvers-types.ts': { - plugins: ['typescript', 'typescript-resolvers'], - }, + "src/schema": defineConfig({ + resolverGeneration: "minimal", + }), }, }; + export default config; ``` -To run the generator: +To generate the resolver types and files, run: ```bash npx graphql-codegen ``` -This creates a set of resolver types like: +This creates resolver files like: ```ts -export type QueryResolvers = { - user?: Resolver>; +import type { QueryResolvers } from "./../../../types.generated"; + +export const user: NonNullable = async ( + _parent, + _arg, + _ctx, +) => { + // Implement Query.user resolver logic here }; ``` -These types ensure that the `user` resolver expects an `id` argument and returns a -`User`, giving you confidence and autocomplete while implementing your server logic. - -## Using generated types in your server - -Once generated, you can use these types directly in your resolver map: +The user query resolver is typed to ensure that the user resolver expects an id argument and returns a +User, giving you confidence and autocomplete while implementing your server logic, which may look like this: ```ts -import { QueryResolvers } from './generated/resolvers-types'; - -export const queryResolvers: QueryResolvers = { - user: (parent, args, context) => { - return context.db.getUser(args.id); - }, +export const user: NonNullable = async ( + parent, + args, + context, +) => { + return context.db.getUser(args.id); }; ``` -You can also extract shared `ContextType` and `Resolver` -utility types from the generated file and apply them across your codebase. +See the official [Server Preset guide](https://the-guild.dev/graphql/codegen/docs/guides/graphql-server-apollo-yoga-with-server-preset) to learn about its other features, including mappers convention and static analysis for runtime safety. ## Generating operation types -In addition to resolver types, you can generate types for GraphQL operations such -as queries, mutations, and fragments. This is especially useful for shared integration tests -or client logic that needs to match the schema precisely. +In addition to resolver types, you can generate types for GraphQL operations such as queries, mutations, and +fragments. This is especially useful for shared integration tests or client logic that needs to match the schema +precisely. -We recommend using the GraphQL Code Generator Server Preset for generating operation types. -The server preset generates both resolver and operation types, without needing to install -or configure additional plugins. +We recommend using the GraphQL Code Generator [Client Preset](https://the-guild.dev/graphql/codegen/plugins/presets/preset-client) for a managed workflow: -Suppose you have a query in `./src/operations/getUser.graphql`: +- Write operations with GraphQL syntax in the same file where it is used +- Get type-safety when using the result -```graphql -query GetUser($id: ID!) { - user(id: $id) { - id - name - } -} -``` - -Update your codegen config: +Here's an example configuration using the Client Preset: ```ts -import type { CodegenConfig } from '@graphql-codegen/cli'; +import type { CodegenConfig } from "@graphql-codegen/cli"; const config: CodegenConfig = { - schema: './schema.graphql', - documents: './src/operations/**/*.graphql', + schema: "src/**/schema.graphql", + documents: ["src/**/*.ts"], + ignoreNoDocuments: true, generates: { - './src/generated/': { - preset: 'graphql-codegen-preset-server', + "./src/graphql/": { + preset: "client", + config: { + documentMode: "string", + }, }, }, }; + export default config; ``` -This produces types like `GetUserQuery` and `GetUserQueryVariables`, which you can -import into your client code or test files. +To keep generated types up to date as you edit your code, run the generator in watch mode: -## Typing resolvers manually +```bash +npx graphql-codegen --config codegen.ts --watch +``` -If you aren't ready to introduce type generation, you can still get partial type safety -using `graphql-js` built-in types. +Once generated, import the `graphql` function from `src/graphql/` to write GraphQL operations +directly in your TypeScript files: ```ts -import { GraphQLFieldResolver } from 'graphql'; +import { graphql } from "./graphql"; + +const UserQuery = graphql(` + query User($id: ID!) { + user(id: ID!) { + id + fullName + } + } +`); -const myResolver: GraphQLFieldResolver = ( - parent, - args, - context, - info -) => { - // ... -}; +const response = await fetch("https://graphql.org/graphql/", { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/graphql-response+json", + }, + body: JSON.stringify({ + query: UserQuery, + variables: { id: "1" }, + }), +}); + +if (!response.ok) { + throw new Error("Network response was not ok"); +} + +const result: ResultOf = await response.json(); + +console.log(result); ``` -This pattern may be enough for small projects or static schemas, but it -can be hard to maintain and scale without automation. +For guides on using the Client Preset with popular frameworks and tools, see: + +- [Vanilla TypeScript](https://the-guild.dev/graphql/codegen/docs/guides/vanilla-typescript) +- [React Query](https://the-guild.dev/graphql/codegen/docs/guides/react-query) +- [React / Vue](https://the-guild.dev/graphql/codegen/docs/guides/react-vue) ## Best practices for CI and maintenance From 8983716a3c2b5aea0e7f06a9b39f9ec994ebe60e Mon Sep 17 00:00:00 2001 From: Sarah Sanders <88458517+sarahxsanders@users.noreply.github.com> Date: Mon, 19 May 2025 19:09:27 -0400 Subject: [PATCH 05/11] Update website/pages/docs/type-generation.mdx Co-authored-by: Eddy Nguyen --- website/pages/docs/type-generation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index fb92493d1b..d9be088f99 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -128,7 +128,7 @@ npx graphql-codegen This creates resolver files like: -```ts +```ts filename="src/schema/user/resolvers/Query/user.ts" import type { QueryResolvers } from "./../../../types.generated"; export const user: NonNullable = async ( From b7eb06c62a587fec1b803433f15dc83dc0167c01 Mon Sep 17 00:00:00 2001 From: Sarah Sanders <88458517+sarahxsanders@users.noreply.github.com> Date: Mon, 19 May 2025 19:09:35 -0400 Subject: [PATCH 06/11] Update website/pages/docs/type-generation.mdx Co-authored-by: Eddy Nguyen --- website/pages/docs/type-generation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index d9be088f99..f05c34462e 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -143,7 +143,7 @@ export const user: NonNullable = async ( The user query resolver is typed to ensure that the user resolver expects an id argument and returns a User, giving you confidence and autocomplete while implementing your server logic, which may look like this: -```ts +```ts filename="src/schema/user/resolvers/Query/user.ts" export const user: NonNullable = async ( parent, args, From 0f50ddbc4baf57bb95c41ed5ab7025db66989da5 Mon Sep 17 00:00:00 2001 From: Sarah Sanders <88458517+sarahxsanders@users.noreply.github.com> Date: Mon, 19 May 2025 19:09:42 -0400 Subject: [PATCH 07/11] Update website/pages/docs/type-generation.mdx Co-authored-by: Eddy Nguyen --- website/pages/docs/type-generation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index f05c34462e..05d496b931 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -168,7 +168,7 @@ We recommend using the GraphQL Code Generator [Client Preset](https://the-guild. Here's an example configuration using the Client Preset: -```ts +```ts filename="codegen.ts" import type { CodegenConfig } from "@graphql-codegen/cli"; const config: CodegenConfig = { From 866ff83f3fbc5da76bb3f6ae45d0127e79b1b267 Mon Sep 17 00:00:00 2001 From: Sarah Sanders <88458517+sarahxsanders@users.noreply.github.com> Date: Mon, 19 May 2025 19:09:49 -0400 Subject: [PATCH 08/11] Update website/pages/docs/type-generation.mdx Co-authored-by: Eddy Nguyen --- website/pages/docs/type-generation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index 05d496b931..5ab93a4983 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -197,7 +197,7 @@ npx graphql-codegen --config codegen.ts --watch Once generated, import the `graphql` function from `src/graphql/` to write GraphQL operations directly in your TypeScript files: -```ts +```ts filename="src/index.ts" import { graphql } from "./graphql"; const UserQuery = graphql(` From b691052ba7c38c0774da097a7d1ade38c9240117 Mon Sep 17 00:00:00 2001 From: sarahxsanders Date: Tue, 20 May 2025 20:19:39 -0400 Subject: [PATCH 09/11] spellcheck --- cspell.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cspell.yml b/cspell.yml index 79e7c13f74..95d52b1a64 100644 --- a/cspell.yml +++ b/cspell.yml @@ -119,3 +119,4 @@ words: - XXXF - bfnrt - wrds + - pgsql \ No newline at end of file From c11f23732337f4e527fb2c7bc76b35e5551e1efb Mon Sep 17 00:00:00 2001 From: sarahxsanders Date: Tue, 27 May 2025 17:20:31 -0400 Subject: [PATCH 10/11] add install steps --- website/pages/docs/type-generation.mdx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index 5ab93a4983..236a7f0a7e 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -80,6 +80,15 @@ With a schema-first workflow, you can: ## Generating resolver types +To get started, install the required packages: + +```bash +npm install graphql @graphql-codegen/cli @eddeee888/gcg-typescript-resolver-files +``` + +This scoped package is publish by a community maintainer and is widely used for GraphQL server +type generation. + We recommend using the [Server Preset](https://www.npmjs.com/package/@eddeee888/gcg-typescript-resolver-files) for a managed workflow. It automatically generates types and files based on your schema without needing extra plugin setup. @@ -91,7 +100,7 @@ The Server Preset generates: This setup expects your schema is split into modules to improve readability and maintainability. For example: -```pgsql +```text ├── src/ │ ├── schema/ │ │ ├── base/ @@ -161,6 +170,12 @@ In addition to resolver types, you can generate types for GraphQL operations suc fragments. This is especially useful for shared integration tests or client logic that needs to match the schema precisely. +To get started, install the required packages: + +```bash +npm install graphql @graphql-codegen/cli +``` + We recommend using the GraphQL Code Generator [Client Preset](https://the-guild.dev/graphql/codegen/plugins/presets/preset-client) for a managed workflow: - Write operations with GraphQL syntax in the same file where it is used From f15186f169d04ec13667a312da684355757ba3ea Mon Sep 17 00:00:00 2001 From: Benjie Date: Thu, 29 May 2025 15:20:34 +0100 Subject: [PATCH 11/11] Apply suggestions from code review --- website/pages/docs/type-generation.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/pages/docs/type-generation.mdx b/website/pages/docs/type-generation.mdx index 236a7f0a7e..fdcaf8e3a4 100644 --- a/website/pages/docs/type-generation.mdx +++ b/website/pages/docs/type-generation.mdx @@ -44,13 +44,13 @@ However, code-first development has tradeoffs: - You won't get automatic type definitions for your resolvers unless you generate them manually or infer them through wrappers. -- Schema documentation, testing, and tool compatibility may require you to export -the schema to SDL first. +- Schema documentation, testing, and tool compatibility may require you to provide + a description of the schema in SDL first. You can still use type generation tools like GraphQL Code Generator in a code-first setup. You just need to convert your schema into SDL. -To export your schema: +To produce an SDL description of your schema: ```ts import { printSchema } from 'graphql'; @@ -60,13 +60,13 @@ import { writeFileSync } from 'fs'; writeFileSync('./schema.graphql', printSchema(schema)); ``` -Once you've written the SDL, you can treat the project like a schema-first project +Once you've written the SDL, you can treat the project like an SDL-first project for type generation. ## Schema-first development In a schema-first workflow, your GraphQL schema is written in SDL, for example, `.graphql` -or `.gql` files. This serves as the source of truth for your server. This approach +or `.gql` (discouraged) files. This serves as the source of truth for your server. This approach emphasizes clarity because your schema is defined independently from your business logic. Schema-first development pairs well with type generation because the schema is @@ -86,7 +86,7 @@ To get started, install the required packages: npm install graphql @graphql-codegen/cli @eddeee888/gcg-typescript-resolver-files ``` -This scoped package is publish by a community maintainer and is widely used for GraphQL server +This scoped package is published by a community maintainer and is widely used for GraphQL server type generation. We recommend using the [Server Preset](https://www.npmjs.com/package/@eddeee888/gcg-typescript-resolver-files) for a