Generate export query.client functions
el-j opened this issue · comments
Hi, i try to find a way using the generated query.client types and functions directly without any useHook implementation, so i can use the react-router v6 way of loading data before rendering any component.
there for it is needed to write the router like mentioned in the example as it will handle the data loading in "loaders" before react lifecycle is used. (cannot use useHooks and needs to use the queryclient directly)
https://reactrouter.com/en/main/guides/data-libs#loading-data
import { queryClient } from "./query-client";
export const loader = ({ params }) => {
return queryClient.fetchQuery(queryKey, queryFn, {
staleTime: 10000,
});
};
or more specific example of a loader:
export const loader =
(queryClient) =>
async ({ request }) => {
const url = new URL(request.url);
const q = url.searchParams.get("q");
if (!queryClient.getQueryData(contactListQuery(q).queryKey)) {
await queryClient.fetchQuery(contactListQuery(q));
}
return { q };
};
Is there any way getting the queries
with queryKey
and queryFn
from the codegen?
thx in advance
Hi,
Interesting usecase!
I'm not sure I have all the moving parts, but let's try! First of all, the {namespace}Context.ts
is just a template (generated only if the file doesn't exist), so you can extract the queryKeyFn
in a separate exported function (
openapi-codegen/plugins/typescript/src/templates/context.ts
Lines 47 to 65 in 13ca9b3
I tried quickly with https://petstore3.swagger.io/api/v3/openapi.json as example, and this is how I could have the types compiled:
import { QueryClient } from "@tanstack/react-query";
import {
fetchFindPetsByStatus,
FindPetsByStatusVariables,
} from "./petstore/petstoreComponents";
import { queryKeyFn } from "./petstore/petstoreContext";
const queryClient = new QueryClient();
const variables: FindPetsByStatusVariables = {};
queryClient.fetchQuery(
queryKeyFn({
operationId: "findPetsByStatus",
path: "/pet/findByStatus",
variables,
}),
({signal}) => fetchFindPetsByStatus(variables, signal),
{
staleTime: 1000,
}
);
I hope this is helping, otherwise I will try a more complete setup 😉
thank you for the quick reply!
yes this was exactly what i was doing here.
- extracting the
queryKeyFn
- try to use the query directly
i opened the issue, because i was looking for a nice way in useing the generated code.
so i would wish to have the 'queries' itself exported for use.
e.g. from your example this would be the code to write:
import { fetchFindPetsByStatusQuery } from 'queries'
queryClient.fetchQuery(fetchFindPetsByStatusQuery(variables),
{
staleTime: 1000,
}
);
and the generator puts out:
{namespace}Queries.ts
export const fetchFindPetsByStatusQuery = (variables) => {
return(
queryKeyFn({
operationId: "findPetsByStatus",
path: "/pet/findByStatus",
variables,
}),
({signal}) => fetchFindPetsByStatus(variables, signal)})
from my point of view, with this approach the generated Component hooks could rely on these queries as well
and the codegen would be much for flexible.
or am i thinking something wrong here?
so the {namespace}Componets.ts
file would look some think like:
import queries from 'queries'
...
export const useFindPetsByStatus = <TData = GetFindPetsByStatusResponse>(
variables: FindPetsByStatusVariables,
options?: Omit<
reactQuery.UseQueryOptions<GetFindPetsByStatusResponse, GetFindPetsByStatusError, TData>,
"queryKey" | "queryFn"
>
) => {
const { fetcherOptions, queryOptions, queryKeyFn } =
useDevApiContext(options);
return reactQuery.useQuery(queries.fetchFindPetsByStatusQuery(variables)),
{
...options,
...queryOptions,
}
);
};
This is quite specific to react-router, but nothing stops us to add a generateReactRouterQueries()
function, you can actually do what ever you want inside openapi-codegen.config.ts
diff --git a/openapi-codegen.config.ts b/openapi-codegen.config.ts
index 3035058..c26a2ed 100644
--- a/openapi-codegen.config.ts
+++ b/openapi-codegen.config.ts
@@ -19,6 +19,11 @@ export default defineConfig({
filenamePrefix,
schemasFiles,
});
+
+ await generateReactRouterComponents(context, {
+ filenamePrefix,
+ schemasFiles,
+ });
},
},
});
This should be quite straightforward to implement, do you want to give a try?
sooo i have done what i needed.
could u please check the pull-request i have opened:
#122
what do you think?
ok so for the useMutation there is something wrong ... i think it's because the return types are just "any" and not really set...
@fabien0102 so i think i am done now, there is now a new plugin creating a {namespace}Functions.ts
file next to the other files. it holds the query-functions for queryClient.fetchQuery()
would be nice if you can review ;)