Back to Graphql Code Generator

typescript-rtk-query

website/src/pages/plugins/typescript/typescript-rtk-query.mdx

1.17.73.1 KB
Original Source

import { Callout } from '@theguild/components' import { PluginApiDocs, PluginHeader } from '@/components/plugin' import { pluginGetStaticProps } from '@/lib/plugin-get-static-props' export const getStaticProps = pluginGetStaticProps(__filename, { hasOperationsNote: true })

<PluginHeader /> <PluginApiDocs />

Usage Examples

<Callout> 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. </Callout>

Using graphql-request

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'{:ts}, so you have to create that file:

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:

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{:ts} to add lifecycle hooks or providesTags/invalidatedTags information to your api:

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:

ts
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