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.

Features

  • 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

Installation

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

Usage

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
├── index.ts
├── schemas.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";
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;

Output directory structure

  • 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
    • requests Output code generated by @hey-api/openapi-ts

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