lukemorales / query-key-factory

A library for creating typesafe standardized query keys, useful for cache management in @tanstack/query
https://www.npmjs.com/package/@lukemorales/query-key-factory
MIT License
1.23k stars 32 forks source link

More ways of structure keys #19

Closed TommySorensen closed 2 years ago

TommySorensen commented 2 years ago

It would be nice to have a third level in the factory. For example if you have 5 different api urls with 30 endpoints underneed and not only a single one

export const cmsKeys = createQueryKeys('cms', {
  content: {
    page: (locale: string, path: string) => [{ locale, path }],
    breadcrumb: (locale: string, path: string) => [{ locale, path }],
  }
});

So i can have a query like ['cms', 'content', 'page', { locale, path }].

Basically i would have multiple swagger interfaces like this one. So in this case i would like ['bff', 'basket', 'baskets', { basketReference }]

image
lukemorales commented 2 years ago

@TommySorensen thanks for the suggestion and for sharing more information about your use cases. FYI v1.0.0 brings support for nested keys and the new API should be available soon, probably next week if the last mile goes smoothly.

TommySorensen commented 2 years ago

@lukemorales Sounds great 👍 One thing i was considering was to also always put the url(without query params) for the fetch function inside the key factory so the react query key, fetch function and the url always go hand in hand. Something like this will work.

export const cmsQueries = createQueryKeys('cms', {
  content: (locale: string, path: string) => ({ locale, path, url: '/some/url' }),
});

export const queries = mergeQueryKeys(cmsQueries);
export type Queries = inferQueryKeyStore<typeof queries>;

function getPage(context: QueryFunctionContext<Queries['cms']['content']>) {
  const { signal, queryKey } = context;
  const [, , { locale, path, url }] = queryKey;

  const searchParams = new URLSearchParams();
  searchParams.set('locale', locale);
  searchParams.set('path', path);

  return ky
    .get(url, { signal })
    .json<Page>();
}
lukemorales commented 2 years ago

@lukemorales Sounds great 👍 One thing i was considering was to also always put the url(without query params) for the fetch function inside the key factory so the react query key, fetch function and the url always go hand in hand. Something like this will work.

export const cmsQueries = createQueryKeys('cms', {
  content: (locale: string, path: string) => ({ locale, path, url: '/some/url' }),
});

export const queries = mergeQueryKeys(cmsQueries);
export type Queries = inferQueryKeyStore<typeof queries>;

function getPage(context: QueryFunctionContext<Queries['cms']['content']>) {
  const { signal, queryKey } = context;
  const [, , { locale, path, url }] = queryKey;

  const searchParams = new URLSearchParams();
  searchParams.set('locale', locale);
  searchParams.set('path', path);

  return ky
    .get(url, { signal })
    .json<Page>();
}

You should already be able to do that? Not sure you're suggesting some feature or just giving an example of an idea you're considering 😅, but I don't see why you wouldn't already be able to do

TommySorensen commented 2 years ago

You should already be able to do that? Not sure you're suggesting some feature or just giving an example of an idea you're considering 😅, but I don't see why you wouldn't already be able to do

I guess it's me trying to give more context to the talk 😀

lukemorales commented 2 years ago

@TommySorensen just letting you know, v1.0 has been released with support for nested keys: https://github.com/lukemorales/query-key-factory/releases/tag/v1.0.0

TommySorensen commented 2 years ago

@lukemorales Yeah thx 👍 I will test it out tomorrow in my project.