TypeScript RTK-Query

Package nameWeekly DownloadsVersionLicenseUpdated
@graphql-codegen/typescript-rtk-queryDownloadsVersionLicenseSep 5th, 2024

Installation

npm i -D @graphql-codegen/typescript-rtk-query
⚠️

Usage Requirements In order to use this GraphQL Codegen plugin, please make sure that you have GraphQL operations (query / mutation / subscription and fragment) set as documents: … in your codegen.yml.

Without loading your GraphQL operations (query, mutation, subscription and fragment), you won’t see any change in the generated output.

Config API Reference

importBaseApiFrom

type: string

Define where to import the base api to inject endpoints into

Usage Examples

codegen.ts
 import type { CodegenConfig } from '@graphql-codegen/cli';
 
 const config: CodegenConfig = {
   // ...
   generates: {
     'path/to/file.ts': {
       plugins: ['typescript', 'typescript-resolvers', 'typescript-rtk-query'],
       config: {
         importBaseApiFrom: 'src/app/api/baseApi',
       },
     },
   },
 };
 export default config;

importBaseApiAlternateName

type: string default: 'api'

Change the import name of the baseApi from default ‘api’

Usage Examples

codegen.ts
 import type { CodegenConfig } from '@graphql-codegen/cli';
 
 const config: CodegenConfig = {
   // ...
   generates: {
     'path/to/file.ts': {
       plugins: ['typescript', 'typescript-resolvers', 'typescript-rtk-query'],
       config: {
         importBaseApiFrom: 'src/app/api/baseApi',
         importBaseApiAlternateName: 'alternateApiName'
       },
     },
   },
 };
 export default config;

exportHooks

type: boolean default: false

Whether to export React Hooks from the generated api. Enable only when using the "@reduxjs/toolkit/query/react" import of createApi

Usage Examples

codegen.ts
 import type { CodegenConfig } from '@graphql-codegen/cli';
 
 const config: CodegenConfig = {
   // ...
   generates: {
     'path/to/file.ts': {
       plugins: ['typescript', 'typescript-resolvers', 'typescript-rtk-query'],
       config: {
         importBaseApiFrom: 'src/app/api/baseApi',
         exportHooks: true
       },
     },
   },
 };
 export default config;

overrideExisting

type: string default: undefined

Sets the overrideExisting option, for example to allow for hot module reloading when running graphql-codegen in watch mode. Will directly be injected as code.

Usage Examples

codegen.ts
 import type { CodegenConfig } from '@graphql-codegen/cli';
 
 const config: CodegenConfig = {
   // ...
   generates: {
     'path/to/file.ts': {
       plugins: ['typescript', 'typescript-resolvers', 'typescript-rtk-query'],
       config: {
         importBaseApiFrom: 'src/app/api/baseApi',
         overrideExisting: 'module.hot?.status() === "apply"'
       },
     },
   },
 };
 export default config;

Usage Examples

💡

Note: this plugin just injects new endpoints into an existing API you created with createApi, so you still have to define that - but also have all freedom on how to do that.

Using graphql-request

codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli'
 
const config: CodegenConfig = {
  schema: 'MY_SCHEMA_PATH',
  documents: './src/**/*.graphql',
  generates: {
    './src/app/api/generated.ts': {
      plugins: [
        'typescript',
        'typescript-operations',
        {
          'typescript-rtk-query': {
            importBaseApiFrom: 'src/app/api/baseApi',
            exportHooks: true
          }
        }
      ]
    }
  }
}
export default config

The generated src/app/api/generated.ts would try to import { api } from 'src/app/api/baseApi', so you have to create that file:

src/app/api/baseApi.ts
import { createApi } from '@reduxjs/toolkit/query/react'
import { graphqlRequestBaseQuery } from '@rtk-query/graphql-request-base-query'
import { GraphQLClient } from 'graphql-request'
 
export const client = new GraphQLClient('/graphql')
 
export const api = createApi({
  baseQuery: graphqlRequestBaseQuery({ client }),
  endpoints: () => ({})
})

From that point on, you can import the generated hooks from src/app/api/generated.ts:

src/components/MyComponent.ts
import { useMyQuery } from 'src/app/api/generated'
 
export const MyComponent = () => {
  const { data, isLoading } = useMyQuery({ page: 5 })
}

Extending generated code

You can import the generated code into a new file and use api.enhanceEndpoints to add lifecycle hooks or providesTags/invalidatedTags information to your api:

src/аpp/api/enhanced.ts
import { api as generatedApi } from 'src/app/api/generated'
 
export const api = generatedApi.enhanceEndpoints({
  addTagTypes: ['User'],
  endpoints: {
    GetUserById: {
      providesTags: (result, error, arg) => [{ type: 'User', id: arg.userId }]
    }
  }
})
 
export const { useGetUserByIdQuery } = api

Make sure that this file is referenced from your code so that the enhanced endpoints are usable. The easiest way to do this is to re-export the hooks in this file and import them exclusively from it.

Setting an authentication header after a Mutation

You can also use this to set an “authentication” header after a login mutation:

import { api as generatedApi } from 'src/app/api/generated'
import { client } from 'src/app/api/baseApi'
 
export const api = generatedApi.enhanceEndpoints({
  endpoints: {
    Login: {
      async onQueryStarted(arg, { queryFulfilled }) {
        const { data } = await queryFulfilled
        client.setHeader('authentication', `Bearer ${data.token}`)
      }
    }
  }
})
 
export const { useLoginMutation } = api