T
TanStack3y ago
generous-apricot

Abstracting correctly useQuery

So in my app, I want to define a set of "API definitions" that are mainly composed of the queryKey and queryFn for each of my possible calls. The idea is that I would like to have an abstraction over useQuery that accept a definition and get/build the key and function. I simplified my usecase for the exemple and made a sandbox: https://codesandbox.io/s/optimistic-shadow-d0u4rb?file=%2Fsrc%2FApp.tsx Like @TkDodo 🔮 and @julien proposed to me already, I gave up on abstracting all the options. But I still want to provide some like initialData, enabled and others. So i am okay to make my own simpler options I face 2 problèms: - types are not perfects, I have a conflict of return types L28, i don't understand it nor knows how to fix it - if i provide initialData, it does not infer properly the types from useQuery, and my data L34 stays possibly undefined. Could you help me understand and fix these issues pleas ? 🙏 Thank you !
9 Replies
generous-apricot
generous-apricotOP3y ago
Is the API definitions a bad idea in the first place ? The other solution is to create a custom hook for each endpoint, but i kinda want to avoid that, i have a lot of endpoints used in multiple apps. In the meantime i am doing it in to calls, one that generates me the keys and api function based on the endpoint and the params, another with useQuery:
const query = useQueryBuilder(enpoints.getThing, { ...params })
const { data } = useQuery(...query, {
initialData: addendums,
})
const query = useQueryBuilder(enpoints.getThing, { ...params })
const { data } = useQuery(...query, {
initialData: addendums,
})
But that's not optimal to have 2 hooks for each calls
sunny-green
sunny-green3y ago
Hi 👋 have you considered using a code generation tool like Orval?
generous-apricot
generous-apricotOP3y ago
Hi ! Thx for your interest in my problem are these mainly based on openAPI definitions ? i think it might be a lot to ask my golang backend team to create/manage it right now in the middle of our project that might be a possibility in the future, i see these problems like technical problem only related to typescript, i would feel bad the propose changing our front/backend workflow just for that
sunny-green
sunny-green3y ago
Yeah, these are based on an API contract which you probably have and probably are generating your TypeScript types from. The specific implementation issue you're facing is related to TypeScript, yes, but you're essentially trying to create queries for each of your endpoints which is something that could be done automatically - it was just a suggestion 🙂 You might want to look at https://tanstack.com/query/v4/docs/react/community/lukemorales-query-key-factory
generous-apricot
generous-apricotOP3y ago
There is no TS in the project, i am in the work of setting it up Sadly I don't have any contract, just a swagger (that might not be up to date for every endpoint) I currently building this "API Definitions" so that I can add types over time when we add a new endpoint / work on an existing one thx i'll look at it
sunny-green
sunny-green3y ago
A Swagger OpenAPI spec is an API contract - you can generate TypeScript types from it No worries 🙂
generous-apricot
generous-apricotOP3y ago
didnt know that ! thx
sunny-green
sunny-green3y ago
Have a look at https://www.npmjs.com/package/openapi-typescript 🙂 Alternatively, let something like Orval generate the types, query/mutation function and hooks for you from the OpenAPI spec
generous-apricot
generous-apricotOP3y ago
I'll look into the types generation from swagger / open api thx ! Query/mutation generation might be another battle tho, i have a tightly complex internal fetching lib linked to a custom store. I was plannin to simplify it one day, but that might be a lot of work to change everything and integrate it with query generation right now

Did you find this page helpful?