I know how to set a requestPolicy per query/operation, but is there a way to set requestPolicy to globally override the default cache-first?
Yes! 馃憤
useQuery accepts it as an option and it's executeQuery callback does as well https://github.com/FormidableLabs/urql/blob/master/src/hooks/useQuery.ts
I think I probably misunderstood this question and you want to set a default requestPolicy on the client, right? https://github.com/FormidableLabs/urql/blob/master/src/client.ts#L30-L37
correct. This is not possible ATM? :disappointed:
Thanks for adding to the roadmap!
It shouldn't take long to add since that was already planned in 馃憤
I'm going to veto this one. I like the idea but there's already a wealth of options for changing the default request policy (create a custom cache exchange or see below) and adding this in will add complexity and reduce the predictability of urql.
I'd advise that you maybe look at proxying the useQuery hook if you want to change default functionality.
// Some util file
import { useQuery as useQueryDefault } from 'urql';
export const useQuery = (arg1, arg2) => useQuery(arg1, {...arg2, cachePolicy: arg2.cachePolicy === undefined ? "preferred-policy" : arg2.cachePolicy });
// importing
import { useQuery } from 'src/utils/urql';
@capaj In terms of the actual default, you can also extend the Client, e.g.:
import { Client, OperationType, GraphQLRequest, OperationContext } from 'urql';
class CustomClient extends Client {
createRequestOperation(
type: OperationType,
request: GraphQLRequest,
opts?: Partial<OperationContext>
) {
const operation = super.createRequestOperation(type, request, opts);
// overriding the default
operation.context.requestPolicy = opts.requestPolicy || 'cache-and-network';
return operation;
}
}
or in plain JS:
import { Client } from 'urql';
class CustomClient extends Client {
createRequestOperation(type, request, opts) {
const operation = super.createRequestOperation(type, request, opts);
operation.context.requestPolicy = opts.requestPolicy || 'cache-and-network';
return operation;
}
}
Let's close this for now, since it's achievable without a change on our end, but we're happy to reopen this for discussion if it's raised again :+1:
Commenting because I think you should consider reopening this feature. It doesn't make a lot of sense having to go extending the client and all of that (specially since it's undocumented) because it can lead to multiple solutions and different code for doing the same thing in different projects. Having a unified way of doing it, like for example:
const client = createClient({
url: '/api/v1/graphql',
defaultCachePolicy: 'network-only',
});
Would be more useful and clearer for new users and people whose entire projects rely on different cache policies.
Also, I don't understand how this can lead to unpredictability when IMO it's actually the opposite, you have a unified place where you can see what's the default cache policy of your project.
For anyone coming across this, here is how we had to override the Client. This is an actual working example, unlike @kitten's.
import {Client as UrqlClient, ClientOptions, OperationType, GraphQLRequest, OperationContext} from "urql";
export class Client extends UrqlClient {
constructor(opts: ClientOptions) {
super(opts);
const createRequestOperation = this.createRequestOperation;
this.createRequestOperation = (
type: OperationType,
request: GraphQLRequest,
options?: Partial<OperationContext>
) => {
return createRequestOperation(type, request, {
...options,
requestPolicy: (options && options.requestPolicy) || "cache-and-network",
});
};
}
}
I too would like to advocate for defaultRequestPolicy on the Client itself. It is pretty ridiculous the hoops we had to jump through to get this working across the entire application. We come from Apollo (as I assume many users do), so this feels like several steps backwards from that.
Yep, you're right. Considering that most OoerstionContext options are exposed it's an odd choice of ours not to allow a default requestPolicy, so I'll reopen the issue and we'll add it in 馃憤
Most helpful comment
Commenting because I think you should consider reopening this feature. It doesn't make a lot of sense having to go extending the client and all of that (specially since it's undocumented) because it can lead to multiple solutions and different code for doing the same thing in different projects. Having a unified way of doing it, like for example:
Would be more useful and clearer for new users and people whose entire projects rely on different cache policies.
Also, I don't understand how this can lead to unpredictability when IMO it's actually the opposite, you have a unified place where you can see what's the default cache policy of your project.