Skip to content

Introduction

OpenAPI React Query Codegen is a code generator for creating React Query (also known as TanStack Query) hooks based on your OpenAPI schema.

  • Generates custom react hooks that use React Query’s useQuery, useSuspenseQuery, useMutation and useInfiniteQuery hooks
  • Generates custom functions that use React Query’s ensureQueryData and prefetchQuery functions
  • Generates query keys and functions for query caching
  • Generates pure TypeScript clients generated by @hey-api/openapi-ts
Terminal window
npm install -D @7nohe/openapi-react-query-codegen

Register the command to the scripts property in your package.json file.

{
"scripts": {
"codegen": "openapi-rq -i ./petstore.yaml"
}
}

You can also run the command without installing it in your project using the npx command.

Terminal window
$ npx --package @7nohe/openapi-react-query-codegen openapi-rq -i ./petstore.yaml

For example, let’s generate React Query hooks for the Petstore API.

Terminal window
npm run codegen

Then you will see the generated code in the openapi directory.

Terminal window
$ tree openapi
openapi/
├── queries
├── common.ts
├── ensureQueryData.ts
├── index.ts
├── infiniteQueries.ts
├── prefetch.ts
├── queries.ts
└── suspense.ts
└── requests
├── client/
├── core/
├── client.gen.ts
├── index.ts
├── sdk.gen.ts
├── services.gen.ts
└── types.gen.ts

Before using the generated hooks, you need to install the required dependencies.

Terminal window
npm install @tanstack/react-query

Then, add the QueryClientProvider to your application’s entry point.

Also, you can set the base URL and interceptors for the client generated by @hey-api/openapi-ts.

src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
// services.gen.ts is a backward-compatibility shim that re-exports from client.gen and sdk.gen
import { client } from "../openapi/requests/services.gen";
client.setConfig({
baseUrl: "YOUR_BASE_URL",
throwOnError: true, // If you want to handle errors on `onError` callback of `useQuery` and `useMutation`, set this to `true`
});
client.interceptors.request.use((config) => {
// Add your request interceptor logic here
return config;
});
client.interceptors.response.use((response) => {
// Add your response interceptor logic here
return response;
});
export const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);

In your React application, you can import the generated hooks and use them like this:

src/App.tsx
import { useFindPets } from "../openapi/queries";
function App() {
const { data, error, refetch } = useFindPets();
if (error)
return (
<div>
<p>Failed to fetch pets</p>
<button type="button" onClick={() => refetch()}>
Retry
</button>
</div>
);
return (
<>
<h1>Pet List</h1>
<ul>{data?.map((pet) => <li key={pet.id}>{pet.name}</li>)}</ul>
</>
);
}
export default App;
  • Directoryopenapi
    • Directoryqueries
      • index.ts Main file that exports common types, variables, and queries. Does not export suspense or prefetch hooks
      • common.ts Common types
      • ensureQueryData.ts Generated ensureQueryData functions
      • queries.ts Generated query/mutation hooks
      • infiniteQueries.ts Generated infinite query hooks
      • suspenses.ts Generated suspense hooks
      • prefetch.ts Generated prefetch functions
    • Directoryrequests Output code generated by @hey-api/openapi-ts
      • Directoryclient/ Hey API client implementation (internal)
      • Directorycore/ Hey API core utilities (internal)
      • client.gen.ts Client instance and configuration
      • sdk.gen.ts SDK functions (primary service functions)
      • services.gen.ts Backward-compatibility shim (re-exports from client.gen and sdk.gen)
      • types.gen.ts Generated TypeScript types
      • index.ts Barrel file

To learn more about prefetchQuery and ensureQueryData functions, check out the following links: