As we've previously seen by generating TypeScript types we can automatically create types based on your projects GraphQL API schema.
Let's take this a step further by generating types for GraphQL queries and mutations inside your project.
Install the following dependencies to get started:
typescript
@graphql-codegen/cli
@graphql-codegen/client-preset
npm install -D typescript @graphql-codegen/cli @graphql-codegen/client-preset
Then inside package.json
add to scripts
a new command:
{
"codegen": "graphql-codegen -r dotenv/config"
}
You'll notice above we're preloading dotenv/config
which means we can use environment variables instead of committing our Grafbase API URL and API Key to source control.
Create .env
in the root of your project and add your project API URL and API Key:
GRAFBASE_API_URL=
GRAFBASE_API_KEY=
Next inside of the project root, create the file codegen.ts
and add your Grafbase API URL and API key:
import { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: {
[process.env.GRAFBASE_API_URL]: {
headers: {
'x-api-key': process.env.GRAFBASE_API_KEY,
},
},
},
}
export default config
Now we've configured the location of the schema we can configure the files we want to generate, and the plugins we want to use.
We'll be using the client-preset
to generate the folder gql
in the root of our project. You can update this to output where you like.
import { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: {
[process.env.GRAFBASE_API_URL]: {
headers: {
'x-api-key': process.env.GRAFBASE_API_KEY,
},
},
},
generates: {
'./gql/': {
preset: 'client',
plugins: [],
},
},
}
export default config
Finally, we'll want to ignore the warnings for no documents:
import { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: {
[process.env.GRAFBASE_API_URL]: {
headers: {
'x-api-key': process.env.GRAFBASE_API_KEY,
},
},
},
generates: {
'./gql/': {
preset: 'client',
plugins: [],
},
},
ignoreNoDocuments: true,
}
export default config
We can now run the script codegen
to generate the TypeScript types for the provided Grafbase API schema:
npm run codegen
At this point GraphQL Code Generator will generate types for the schema, but it doesn't yet know about any GraphQL operations — we'll change that next!
Inside your codegen.ts
you can provide a glob for files that contain your GraphQL operations. We'll use the app
directory in this example:
import { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
schema: {
[process.env.GRAFBASE_API_URL]: {
headers: {
'x-api-key': process.env.GRAFBASE_API_KEY,
},
},
},
generates: {
'./gql/': {
preset: 'client',
plugins: [],
},
},
ignoreNoDocuments: true,
documents: ['app/**/*.{ts,tsx}'],
}
export default config
You'll notice here that we provide the glob to .{ts,tsx}
files and not .{gql,graphql}
like you may have been used to doing before with GraphQL Code Generator. You should now write GraphQL queries, mutations, and fragments inside files that use them.
You'll want to change the directory app
if that's not where your pages/components are stored.
So that GraphQL Code Generator can correctly type any operations you will need to use the newly exported graphql
function from the directory ./gql
(or whatever you named it).
Inside of your application you will want to import graphql
and pass your operation to it:
import { graphql } from '../gql'
const GetAllPostsDocument = graphql(/* GraphQL */ `
query GetAllPosts {
postCollection(first: 10) {
edges {
node {
title
published
author {
name
}
}
}
}
}
`)
You can now run the codegen
script to generate the types for your API and GraphQL operations:
npm run codegen
GraphQL Code Generator will now generate a TypedDocumentNode
that you can pass to a client library that supports it so you have full type-safety.
You can use the --watch
flag to watch for any changes instead of manually invoking codegen
after every change:
{
"codegen": "graphql-codegen -r dotenv/config",
"watch": "graphql-codegen -r dotenv/config --watch"
}
That's it! — You now have TypeScript types for your API and GraphQL operations.