Skip to content

Latest commit

 

History

History
171 lines (131 loc) · 5.41 KB

code-generation.mdx

File metadata and controls

171 lines (131 loc) · 5.41 KB
id title sidebar_label hide_title description
code-generation
Code Generation
Code Generation
true
RTK Query > Usage > Code Generation: automated creation of API code

 

Code Generation

RTK Query's API and architecture is oriented around declaring API endpoints up front. This lends itself well to automatically generating API slice definitions from external API schema definitions, such as OpenAPI and GraphQL.

We have early previews of code generation capabilities available as separate tools.

GraphQL

We provide a Plugin for GraphQL Codegen. You can find the documentation to that on the graphql-codegen homepage.

For a full example on how to use it, you can see this example project.

OpenAPI

We provide a package for RTK Query code generation from OpenAPI schemas. It is published as @rtk-query/codegen-openapi and you can find the source code at packages/rtk-query-codegen-openapi.

Usage

Create an empty api using createApi like

// Or from '@reduxjs/toolkit/query' if not using the auto-generated hooks
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

// initialize an empty api service that we'll inject endpoints into later as needed
export const emptySplitApi = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/' }),
  endpoints: () => ({}),
})

Generate a config file (json, js or ts) with contents like

import type { ConfigFile } from '@rtk-query/codegen-openapi'

const config: ConfigFile = {
  schemaFile: 'https://petstore3.swagger.io/api/v3/openapi.json',
  apiFile: './src/store/emptyApi.ts',
  apiImport: 'emptySplitApi',
  outputFile: './src/store/petApi.ts',
  exportName: 'petApi',
  hooks: true,
}

export default config

and then call the code generator:

npx @rtk-query/codegen-openapi openapi-config.ts

Generating tags

If your OpenAPI specification uses tags, you can specify the tag option to the codegen.
That will result in all generated endpoints having providesTags/invalidatesTags declarations for the tags of their respective operation definition.

Note that this will only result in string tags with no ids, so it might lead to scenarios where too much is invalidated and unneccessary requests are made on mutation.

In that case it is still recommended to manually specify tags by using addTagTypes and enhanceEndpoint on top of the generated api and manually declare providesTags/invalidatesTags.

Programmatic usage

import { generateEndpoints } from '@rtk-query/codegen-openapi'

const api = await generateEndpoints({
  apiFile: './fixtures/emptyApi.ts',
  schemaFile: resolve(__dirname, 'fixtures/petstore.json'),
  filterEndpoints: ['getPetById', 'addPet'],
  hooks: true,
})

Config file options

Simple usage

interface SimpleUsage {
  apiFile: string
  schemaFile: string
  apiImport?: string
  exportName?: string
  argSuffix?: string
  responseSuffix?: string
  hooks?:
    | boolean
    | { queries: boolean; lazyQueries: boolean; mutations: boolean }
  tag?: boolean
  outputFile: string
  filterEndpoints?:
    | string
    | RegExp
    | EndpointMatcherFunction
    | Array<string | RegExp | EndpointMatcherFunction>
  endpointOverrides?: EndpointOverrides[]
  flattenArg?: boolean
}

export type EndpointMatcherFunction = (
  operationName: string,
  operationDefinition: OperationDefinition,
) => boolean

Filtering endpoints

If you only want to include a few endpoints, you can use the filterEndpoints config option to filter your endpoints. Note that endpoints are transformed to camel case. For example, login_user will become loginUser. filterEndpoints will be checked against this camel case version of the endpoint.

const filteredConfig: ConfigFile = {
  // ...
  // should only have endpoints loginUser, placeOrder, getOrderById, deleteOrder
  filterEndpoints: ['loginUser', /Order/],
}

Endpoint overrides

If an endpoint is generated as a mutation instead of a query or the other way round, you can override that:

const withOverride: ConfigFile = {
  // ...
  endpointOverrides: [
    {
      pattern: 'loginUser',
      type: 'mutation',
    },
  ],
}

Generating hooks

Setting hooks: true will generate useQuery and useMutation hook exports. If you also want useLazyQuery hooks generated or more granular control, you can also pass an object in the shape of: { queries: boolean; lazyQueries: boolean; mutations: boolean }.

Multiple output files

const config: ConfigFile = {
  schemaFile: 'https://petstore3.swagger.io/api/v3/openapi.json',
  apiFile: './src/store/emptyApi.ts',
  outputFiles: {
    './src/store/user.ts': {
      filterEndpoints: [/user/i],
    },
    './src/store/order.ts': {
      filterEndpoints: [/order/i],
    },
    './src/store/pet.ts': {
      filterEndpoints: [/pet/i],
    },
  },
}