Introduction
Fork of openapi-react-query in openapi-ts/openapi-typescript, maintained by Vladimir Iglovikov. Original authorship and MIT license notices are preserved.
@ternaus/openapi-react-query is a typed client for @tanstack/react-query to work with OpenAPI schema.
TypeScript checks request fields and infers response shapes from the types generated by openapi-typescript. The client sends requests through openapi-fetch.
import createFetchClient from "@ternaus/openapi-fetch";
import createClient from "@ternaus/openapi-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript
const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
const $api = createClient(fetchClient);
const MyComponent = () => {
const { data, error, isLoading } = $api.useQuery(
"get",
"/blogposts/{post_id}",
{
params: {
path: { post_id: 5 },
},
},
);
if (isLoading || !data) return "Loading...";
if (error) return `An error occured: ${error.message}`;
return <div>{data.title}</div>;
};Setup
Requires React 19 and TanStack Query 5.
Install this library along with openapi-fetch and openapi-typescript:
npm i @ternaus/openapi-react-query @ternaus/openapi-fetch
npm i -D @ternaus/openapi-typescript typescripttip Highly recommended
Enable noUncheckedIndexedAccess in your
tsconfig.json(docs)
Next, generate TypeScript types from your OpenAPI schema using openapi-typescript:
npx @ternaus/openapi-typescript ./path/to/api/v1.yaml -o ./src/lib/api/v1.d.tsBasic usage
Once your types has been generated from your schema, you can create a fetch client, a react-query client and start querying your API.
import createFetchClient from "@ternaus/openapi-fetch";
import createClient from "@ternaus/openapi-react-query";
import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript
const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
const $api = createClient(fetchClient);
const MyComponent = () => {
const { data, error, isLoading } = $api.useQuery(
"get",
"/blogposts/{post_id}",
{
params: {
path: { post_id: 5 },
},
},
);
if (isLoading || !data) return "Loading...";
if (error) return `An error occured: ${error.message}`;
return <div>{data.title}</div>;
};tip You can find more information about
createFetchClienton the openapi-fetch documentation.
Cache identity and HTTP errors
Query keys include the fetch client's normalized baseUrl, an optional cacheKey, the query mode, HTTP method, path, and fetch options. Normal and infinite queries have separate keys. Clients with the same base URL share their cache by default.
For different users or middleware on one server, give each client a stable cache key:
const $api = createClient(fetchClient, {
cacheKey: "user-123",
});Use $api.queryOptions(method, path, init).queryKey when reading or invalidating a normal query. Keys from older versions have a different shape; rebuild them when upgrading. Query settings such as retry belong in the fourth argument, after the fetch options.
Unsuccessful HTTP responses reject with their parsed error payload. If the body is empty, they reject with an Error whose message includes the HTTP status and whose cause is the original Response. The public error type includes Error. Empty successful queries return null; successful mutations keep their original data, including undefined for an empty body.