orval icon indicating copy to clipboard operation
orval copied to clipboard

Customize default query keys

Open mpetito-envative opened this issue 4 years ago • 33 comments

Is it possible to configure the convention used for query key generation?

I see that you can override the query key when using the generated hook, but this requires remembering to do so each time. Instead, I'd like to configure how the query key is constructed project-wide because our APIs already have consistent hierarchical routes.

For ex., instead of this generated query key:

export const getGetResourceByIdQueryKey = (resourceId: number,) => [`/resource/${resourceId}`];

It would make a lot more sense in my project for the query key to be split by path segments, e.g.:

['resource', resourceId]

I don't see any obvious way to configure or override the convention used for query keys.

My motivation is to simplify query invalidation by having predictable query keys and support prefix invalidation.

mpetito-envative avatar Nov 01 '21 17:11 mpetito-envative

Hello @mpetito-envative, not really the only thing that you can do at the moment is to override the options in the orval config. Could be a new option but how would you do it?

anymaniax avatar Nov 01 '21 17:11 anymaniax

It seems like this would be a runtime behavior because the queryKey depends on properties passed into the query hook.

It is already possible to do something similar with the mutator override for the purpose of replacing the http request. Perhaps a queryKey override would allow for replacement of the queryKeyFn at runtime?

Alternatively (or in addition), it might make sense to change the default convention used for queryKey generation. I know this would be a breaking change, but I can't think of any disadvantage to splitting the route on / and it would offer an easy path for prefix invalidation if routes already represent a hierarchy.

mpetito-envative avatar Nov 01 '21 22:11 mpetito-envative

It's also what I thought but if we do a sort of mutator I will need to pass the route and all params to the function. For the other one, could make sense but since it's a breaking change I will add it for the next major release

anymaniax avatar Nov 02 '21 07:11 anymaniax

@anymaniax Any updates on this? This issue just bit me and I'm not sure how to move forward without hardcoding the path in some form and matching with a predicate.

vezaynk avatar Apr 05 '22 17:04 vezaynk

+1. This is an awesome tool but the queryKey is blocking me from using it. Is there a workaround before it get addressed?

missing1984 avatar Jul 10 '22 02:07 missing1984

@missing1984 it's on my todo list for the next version. Sorry I have a lot of stuff to do lately

anymaniax avatar Jul 10 '22 10:07 anymaniax

Another use case for query-key customisation is when there are more than one orval-generated api clients. If both have a /version endpoint for example, then the queries keys clash.

OliverDudgeon avatar Aug 24 '22 17:08 OliverDudgeon

Did you guys manage to find a workaround?

la55u avatar Oct 25 '22 12:10 la55u

I wrote a custom script base on "ts-morph" to process the generated file. It will be great to have native support though

missing1984 avatar Nov 16 '22 02:11 missing1984

@missing1984 Can you share it?

vezaynk avatar Nov 16 '22 02:11 vezaynk

@knyzorg sure, https://gist.github.com/missing1984/907c2b6aef0206e8944ccbaea7c4d0a9 the script basically break key into arrays

missing1984 avatar Nov 16 '22 02:11 missing1984

I found a changelog item in 6.11. Is this possible now, I can't find an example in the doc. @anymaniax

missing1984 avatar Feb 10 '23 03:02 missing1984

Hello @missing1984, you can do it with this and you can do the same with the property queryKey only. It’s completely new and the doc is not complete about it but it’s like a mutator.

anymaniax avatar Feb 10 '23 06:02 anymaniax

Has anyone got this solution working? My queryOptions function isn't run by orval.

OliverDudgeon avatar Feb 27 '23 22:02 OliverDudgeon

What is your config @OliverDudgeon?

anymaniax avatar Feb 27 '23 23:02 anymaniax

The queryOptions mutator function is used in the generated file but not imported.

I have this block in my config

{
	query: {
		useQuery: true,
		queryOptions: './src/queryMutator.ts',
	},
}

mutator is the default export of that file:

// src/queryMutator.ts
export const mutator = (args: any) => {
  console.log('Mutator:');
  console.log(args);
};

export default mutator;

In generated hooks,

const customOptions = getAssetQueryOptionsMutator({
  ...queryOptions,
  queryKey,
  queryFn,
});

is generated but ts errors on getAssetQueryOptionsMutator as it isn't imported.

If I use

{
	query: {
		useQuery: true,
		queryOptions: {
			path: './src/queryMutator.ts',
			name: 'mutator',
		},
	},
}
then this is generated in hooks

```ts
const customOptions = mutator({ ...queryOptions, queryKey, queryFn });

but mutator isn't imported.

There isn't anything in the orval logs.

OliverDudgeon avatar Feb 28 '23 18:02 OliverDudgeon

@OliverDudgeon you have the last version of orval?

anymaniax avatar Feb 28 '23 22:02 anymaniax

Using 6.12.0

OliverDudgeon avatar Feb 28 '23 22:02 OliverDudgeon

I am currently trying on the react basic samples with this config and it seems to work properly.

import { defineConfig } from 'orval';

export default defineConfig({
  petstore: {
    output: {
      target: 'src/api/endpoints/petstoreFromFileSpecWithTransformer.ts',
      schemas: 'src/api/model',
      client: 'react-query',
      override: {
        query: {
          useQuery: true,
          queryOptions: {
            path: './src/api/mutator/queryMutator.ts',
            name: 'mutator',
          },
        },
      },
    },
    input: {
      target: './petstore.yaml',
    },
  },
});

anymaniax avatar Feb 28 '23 22:02 anymaniax

@OliverDudgeon Do You have extra information that can help me reproduce this?

anymaniax avatar Feb 28 '23 22:02 anymaniax

Don't have time tonight to figure out a minimal example but here is what I have.

This is my project, https://github.com/InformaticsMatters/squonk2-openapi-js-client-generator.

  1. Update orval to @latest
  2. Place this OpenApi, https://pastebin.com/EsN5cVUW, in the root as openapi.yaml
  3. Add the mutator file below this
  4. Add a path to it in queryOptions
  5. Run npm i && npm run orval
// // src/queryMutator.ts
export const mutator = (args: any) => {
  console.log('Mutator:');
  console.log(args);

  return args;
};

export default mutator;

OliverDudgeon avatar Feb 28 '23 23:02 OliverDudgeon

Hello @OliverDudgeon, I can reproduce a problem only when I use the path directly like the following. Otherwise it seems to work properly

{
 query: {
  queryOptions: './src/queryMutator'
}
}

anymaniax avatar Mar 02 '23 08:03 anymaniax

@OliverDudgeon I did a fix will be in the next release

anymaniax avatar Mar 02 '23 09:03 anymaniax

Ok this is even more strange. On 6.12.0, the error only happens on some of the generated files. I'm using mode: 'tags-split'. Two of my tags have the import statement missing when the others are fine.

I will try get your recent commit working to test it out.

OliverDudgeon avatar Mar 02 '23 10:03 OliverDudgeon

Great, the update on master seems to fix the issue. Cheers!

OliverDudgeon avatar Mar 02 '23 10:03 OliverDudgeon

hmm, i did try out the mutator but i found the getXXXQueryKey function remains unchanged. We're rely on this function to do cache invalidation..

Any idea how can i override the key getter function? @anymaniax

missing1984 avatar Aug 11 '23 20:08 missing1984

Hi, @missing1984

In the version 6.24.0 it is possible to override keys by specifying options in the custom hook that is generated. Could you please check this?

soartec-lab avatar Feb 05 '24 00:02 soartec-lab