ecyrbe / zodios-react

React hooks for zodios
MIT License
64 stars 12 forks source link

Better way to access generated keys #115

Closed Todomir closed 2 years ago

Todomir commented 2 years ago

Currently, the only way to get the key of an particular query is by using the provided useQuery hook, but it would be more useful to have an way to access keys both inside and outside of components. The class could expose an getKeyByAlias or getKeyByPath to allow key access outside of components. A good use case for that is integrating with React Router's loaders and actions, since they are created outside components.

import { Zodios } from '@zodios/core';
import { ZodiosHooks } from '@zodios/react';

const api = new Zodios(
    'https://jsonplaceholder.typicode.com',
    [{
        path: 'user/:id'
        alias: 'getUser',
        ...
    }]
)

const hooks = new ZodiosHooks('users', ZodiosAPI);
export const loader = async ({ params }) => {
  const queryKey = hooks.getKeyByAlias('getUser', { params: { id: params.id } });
  return (
    queryClient.getQueryData(queryKey) ??
    (await queryClient.fetchQuery(api.getUser({ params: { id: params.id } })))
  )
}
ecyrbe commented 2 years ago

Nice Idea. I also had this in mind. Thanks for opening this issue.

Todomir commented 2 years ago

Nice Idea. I also had this in mind. Thanks for opening this issue.

Yeah, I think it would be a great improvement to an already great library :)

ecyrbe commented 2 years ago

So when starting designing this, i came with 4 added methods.

The first two are straighforward from your issue:

function getAliasKey(alias,params);
function getEndpointKey(method,path,params);

The other two, serve as a complete endpoint cache invalidation, that will invalidate the cache for all possible parameters:

function getAliasInvalidationKey(alias);
function getEndpointInvalidationKey(method,path);

what do you think ?

Todomir commented 2 years ago

Yeah, didn't even think about an invalidation method, but in retrospect it would be pretty useful. Maybe rename to invalidateQueryByAlias and invalidateQueryByPath would better describe the methods

Todomir commented 2 years ago

Or they would actually return the key?

ecyrbe commented 2 years ago

yes, i was thinking they would return the key here. But actually, your suggestion makes a lot of sense. it's better aligned with what we are trying to do here and with the rest of zodios. to have function helpers to invalidate the cache.

which one would you prefer :

Todomir commented 2 years ago

Yeah, I think keys are useful for more than just invalidation (like implementing optimistic UI updates by directly mutating the cache), and having an helper for invalidation is pretty useful as well, so both would be nice. I guess it would make more sense, instead of having one method to get the key with params, and other to get the keys for a complete endpoint invalidation, for they to be the same method and the params are just an optional argument. Don't know how doable it is, but DX wise it makes more sense IMO

ecyrbe commented 2 years ago

oh, don't mind... invalidation cache helpers are not doable.
indeed, access to queryclient is only available as a hook to invalidate cache. (only available in react context)

ecyrbe commented 2 years ago

so i guess i'll stick to option 1.

Todomir commented 2 years ago

I think that the key helpers are more useful than the invalidation helpers anyways, because once I have access to keys I can invalidate manually

Todomir commented 2 years ago

If I need the invalidation helpers, I can just use the one that the query hook returns.

ecyrbe commented 2 years ago

ok, so your other suggestion should be doable to not provide parameters and this way get back the global endpoint invalidation key. it will make documentation just a little more complex to explain this. but by adding proper examples this should be ok.

ecyrbe commented 2 years ago

I also like the naming so in the end we will have :

function getKeyByAlias(alias: string,params?: Config): QueryKey;
function getKeyByPath(method: string,path: string,params?: Config): QueryKey;
ecyrbe commented 2 years ago

Done! It's available on v9.4 of @zodios/react and also on 9.1 of @zodios/solid. Documentation is also updated: https://www.zodios.org/docs/client/react#zodios-key-helpers