OpenAPI React Query Codegen
repository·main·Indexed 19 days ago
https://github.com/7nohe/openapi-react-query-codegenA code generation tool that automates the creation of type-safe TanStack Query (React Query) hooks and utility functions from an OpenAPI schema. It generates custom hooks for useQuery, useSuspenseQuery, useMutation, and useInfiniteQuery, along with data-fetching utilities for prefetching and synchronization. The tool leverages @hey-api/openapi-ts to produce TypeScript clients and provides configurable CLI options for input schemas, output directories, and HTTP clients like @hey-api/client-fetch or @hey-api/client-axios.
What's inside @7nohe/openapi-react-query-codegen
- OpenAPI React Query Codegen is a code generator that creates React Query (TanStack Query) hooks based on your OpenAPI schema. It automates the creation of type-safe data fetching logic, reducing boilerplate when integrating an OpenAPI-documented backend with a React application.
Overview of OpenAPI React Query Codegen
mainOpenAPI React Query Codegen is a code generator designed to create React Query (TanStack Query) hooks directly from your OpenAPI schema. It automates the creation of data-fetching logic, ensuring your frontend hooks are always in sync with your API definitions.Features of OpenAPI React Query Codegen
mainThe generator provides several key automation features for React applications:
- Custom React Hooks: Automatically generates hooks utilizing React Query's core primitives:
useQuery,useSuspenseQuery,useMutation, anduseInfiniteQuery. - Data Fetching Utilities: Generates custom functions that wrap React Query's
ensureQueryDataandprefetchQueryfor efficient data prefetching and synchronization. - Query Key Management: Generates structured query keys and query functions to facilitate robust query caching.
- TypeScript Client Integration: Produces pure TypeScript clients by leveraging @hey-api/openapi-ts.
- Custom React Hooks: Automatically generates hooks utilizing React Query's core primitives:
Key features of OpenAPI React Query Codegen
mainThe tool provides three main capabilities for building type-safe React applications:
- React Query Hooks: Generates custom hooks that wrap TanStack Query's core primitives:
useQuery,useSuspenseQuery,useMutation, anduseInfiniteQuery. - Prefetching & Router Integration: Generates custom functions utilizing React Query's
ensureQueryDataandprefetchQuery. This allows for seamless integration with modern frameworks like Next.js and Remix for server-side prefetching or router-based data loading. - Pure TypeScript Clients: Leverages
@hey-api/openapi-tsto generate pure TypeScript clients, enabling type-safe API calls even in environments where you are not using React Query.
- React Query Hooks: Generates custom hooks that wrap TanStack Query's core primitives:
Preview the documentation locally
mainTo preview the documentation site in your local development environment, run the following command from the root of the repository. This uses
pnpmwith a filter to target thedocspackage.pnpm --filter docs devManage dependency type patches
mainThe project uses
skipLibCheck: false, meaning type errors in dependency declaration files will fail the build. To manage this, the project uses two mechanisms:patches/: Contains pnpm patches that add// @ts-ignoreto known typing bugs in@hey-api/openapi-tsand@hey-api/shareddeclaration files.src/vendor-typestubs.d.ts: Stubs modules referenced by@hey-api/openapi-tsbut not installed (e.g.,ky,ofetch,nuxt/app,@angular/*).
How to update patches for
@hey-api/openapi-tsWhen upgrading
@hey-api/openapi-ts, you must recreate the patches:- Run the patch command for the new version.
- Edit the files in the directory printed by the command.
- Commit the patch.
- Run
pnpm buildto verify that no declaration errors remain.
pnpm patch @hey-api/openapi-ts@<new-version> # edit the printed directory, then pnpm patch-commit <printed-directory>Set up the development environment
mainTo contribute to this project, ensure you have the following prerequisites installed:
- Node.js v24 or later
- pnpm v9
Then, install the project dependencies using pnpm:
pnpm installRun development tasks and validation
mainUse the following commands to run tests, linting, and other maintenance tasks:
- Run tests:
pnpm test - Run linter:
pnpm lint - Run linter and fix:
pnpm lint:fix - Update snapshots:
pnpm snapshot - Build example and validate generated code: This command builds the project, generates the API in the
@7nohe/react-apppackage, and then runs tests on the generated code to ensure correctness. - Preview the docs: Starts the documentation server for the
docspackage.
# Build example and validate generated code npm run build && pnpm --filter @7nohe/react-app generate:api && pnpm --filter @7nohe/react-app test:generated # Preview the docs pnpm --filter docs dev- Run tests:
Using the generated `useMutation` hooks and invalidating queries
mainUse the generated
useMutationhooks (e.g.,useAddPet) to perform side effects.Important: Cache Invalidation To ensure your UI reflects the changes made by a mutation, you must invalidate the relevant queries using
queryClient.invalidateQueries. To ensure the query key is constructed exactly as the hook expects (ensuring correct typing and cache matching), use the exportedKeyFnprovided for that specific query (e.g.,UseFindPetsByStatusKeyFn).import { useFindPetsByStatus, useAddPet, UseFindPetsByStatusKeyFn, } from "../openapi/queries"; function App() { const [status, setStatus] = React.useState(["available"]); const { data } = useFindPetsByStatus({ query: { status } }); const { mutate } = useAddPet({ onSuccess: () => { queryClient.invalidateQueries({ // Use the generated KeyFn to ensure the key matches the hook exactly queryKey: [UseFindPetsByStatusKeyFn({ status })], }); }, }); return ( <div className="App"> <button onClick={() => mutate({ name: "Fluffy", status: "available" })}>Add Pet</button> </div> ); }Using the generated `useQuery` hooks
mainYou can use the auto-generated React Query hooks directly to fetch data. These hooks are typically exported from
../openapi/queries.If you need more control, you can use the pure TypeScript SDK functions (defined in
openapi/requests/sdk.gen.tsor theopenapi/requests/services.gen.tsshim) with the standard@tanstack/react-queryuseQueryhook. To maintain consistency and type safety, use the auto-generated query key function (e.g.,useFindPetsKey) provided by the generated files.import { useFindPets } from "../openapi/queries"; function App() { const { data } = useFindPets(); return ( <div className="App"> <h1>Pet List</h1> <ul>{data?.map((pet) => <li key={pet.id}>{pet.name}</li>)}</ul> </div> ); }Using the generated `useInfiniteQuery` hooks
mainThe codegen automatically generates infinite query hooks in
infiniteQueries.tsif your OpenAPI schema meets two criteria:- A parameter name matches the
pageParamoption (e.g.,page). - A response property name matches the
nextPageParamoption (e.g.,nextPage).
Configuration Details:
initialPageParam: Sets the starting page (defaults to1).nextPageParam: Supports dot notation for accessing nested values in the response (e.g.,meta.next).
import { useFindPaginatedPetsInfinite } from "@/openapi/queries/infiniteQueries"; const { data, fetchNextPage } = useFindPaginatedPetsInfinite({ query: { tags: [], limit: 10 } });- A parameter name matches the
Using the generated `useQuerySuspense` hooks
mainThe codegen provides suspense-compatible hooks (e.g.,
useFindPetsSuspense) exported from../openapi/queries/suspense. These hooks are designed to work with React's<Suspense>boundary, allowing you to handle loading states at a component tree level rather than inside the hook itself.import { useFindPetsSuspense } from "../openapi/queries/suspense"; function ChildComponent() { const { data } = useFindPetsSuspense({ query: { tags: [], limit: 10 }, }); return <ul>{data?.map((pet, index) => <li key={pet.id}>{pet.name}</li>)}</ul>; } function ParentComponent() { return ( <> <Suspense fallback={<>loading...</>}> <ChildComponent /> </Suspense> </> ); }