Generated Files
A tour of the five files generated for each controller.
Each controller folder contains five files: types.ts, apis.ts, queries.ts,
mutations.ts, and an index.ts barrel. The examples below are real output
from a Spring Boot (springdoc) API configured with a generic response.envelope
(CommonResponse), response.dataField: "data", and error.
types.ts
Every named schema reachable from the controller’s operations is emitted here,
transitively. Object schemas become interfaces; unions/enums become type
aliases. description becomes JSDoc.
export interface Detail { id?: number; name: string; status?: "ACTIVE" | "ARCHIVED" | "DELETED"; tags?: Array<Tag>;}
export interface Tag { id?: number; label?: string;}apis.ts
Plain functions calling your axios instance. Every function takes a single
object argument containing all of { ...pathParams, body, params, headers }
that the operation needs — so call sites are named and order-independent, which
matters once an endpoint has more than one path param.
import { axiosInstance as client } from "@/lib/axios";import type { CommonResponse } from "@/lib/axios";import type { Detail, Create } from "./types";
/** Get contact details */export const getContact = ({ contactId }: { contactId: number }) => client.get<CommonResponse<Detail>>(`/api/v1/contacts/${contactId}`).then((res) => res.data.data);
/** Create a contact */export const createContact = ({ body }: { body: Create }) => client.post<CommonResponse<Create>>(`/api/v1/contacts`, body).then((res) => res.data.data);
/** Delete a single contact (soft) */export const deleteContact = ({ contactId }: { contactId: number }) => client.delete<CommonResponse<unknown>>(`/api/v1/contacts/${contactId}`).then((res) => res.data.data);queries.ts
The v5 queryOptions pattern, exported as <controller>Queries. The
queryKey is [controllerDir, operationName, ...args].
import { queryOptions } from "@tanstack/react-query";import type { AxiosError } from "axios";import type { ApiError } from "@/lib/axios";import * as apis from "./apis";
export const contactQueries = { getContact: (args: { contactId: number }) => queryOptions<Awaited<ReturnType<typeof apis.getContact>>, AxiosError<ApiError>>({ queryKey: ["contact", "getContact", args], queryFn: () => apis.getContact(args), }),};The options object is reusable across
useQuery,useSuspenseQuery,prefetchQuery,ensureQueryData,invalidateQueries, etc.
mutations.ts
One useXxx hook per mutating endpoint. Each accepts an optional
UseMutationOptions (minus mutationFn), so you can pass onSuccess,
onError, retry, … The mutation’s variables is the same single object the
api takes ({ ...pathParams, body, params, headers }).
import { useMutation } from "@tanstack/react-query";import type { UseMutationOptions } from "@tanstack/react-query";import type { AxiosError } from "axios";import type { ApiError } from "@/lib/axios";import * as apis from "./apis";import type { Create, Update } from "./types";
/** Create a contact */export const useCreateContact = ( options?: Omit< UseMutationOptions< Awaited<ReturnType<typeof apis.createContact>>, AxiosError<ApiError>, { body: Create } >, "mutationFn" >,) => useMutation({ mutationFn: (vars: { body: Create }) => apis.createContact(vars), ...options, });
/** Update a contact (path param + body) */export const useUpdateContact = ( options?: Omit< UseMutationOptions< Awaited<ReturnType<typeof apis.updateContact>>, AxiosError<ApiError>, { contactId: number; body: Update } >, "mutationFn" >,) => useMutation({ mutationFn: (vars: { contactId: number; body: Update }) => apis.updateContact(vars), ...options, });The mutation’s
variablesis the api’s object argument, so every hook is called the same way:mutate({ ...pathParams, body, params }).
index.ts
A per-controller barrel:
export * from "./types";export * from "./apis";export * from "./queries";export * from "./mutations";Import from a specific file or the folder:
import { contactQueries } from "@/api/contact/queries";// orimport { contactQueries, useCreateContact, type Detail } from "@/api/contact";Related
- Output Structure — the folder layout.
- Using the Generated Code — query, mutate, invalidate, prefetch.