Skip to content

Commit

Permalink
fix(persisted): persisted queries can use GETs within URL limits (#3192)
Browse files Browse the repository at this point in the history
  • Loading branch information
NWRichmond authored Apr 28, 2023
1 parent 60281ab commit 9d793b2
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/fair-eels-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@urql/exchange-persisted': major
---

Update the `preferGetForPersistedQueries` option to include the `'force'` and `'within-url-limit'` values from the Client's `preferGetMethod` option. The default value of `true` no longer sets `OperationContext`'s `preferGetMethod` setting to `'force'`. Instead, the value of `preferGetForPersistedQueries` carries through to the `OperationContext`'s `preferGetMethod` setting for persisted queries.
8 changes: 4 additions & 4 deletions docs/advanced/persistence-and-uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ const client = new Client({
});
```

As we can see, typically it's recommended to set `preferGetForPersistedQueries` to `true` to force
all persisted queries to use GET requests instead of POST so that CDNs can do their job.
It does so by setting the `preferGetMethod` option to `'force'` when it's
updating operations.
As we can see, typically it's recommended to set `preferGetForPersistedQueries` to `true`
to encourage persisted queries to use GET requests instead of POST so that CDNs can do their job.
When set to `true` or `'within-url-limit'`, persisted queries will use GET requests if the
resulting URL doesn't exceed the 2048 character limit.

The `fetchExchange` can see the modifications that the `persistedExchange` is
making to operations, and understands to leave out the `query` from any request
Expand Down
18 changes: 18 additions & 0 deletions exchanges/persisted/src/persistedExchange.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,21 @@ it('retries query persisted query resulted in unsupported', async () => {

expect(operations[2].extensions).toEqual(undefined);
});

it.each([true, 'force', 'within-url-limit'] as const)(
'sets `context.preferGetMethod` to %s when `options.preferGetForPersistedQueries` is %s',
async preferGetMethodValue => {
const { exchangeArgs } = makeExchangeArgs();

const res = await pipe(
fromValue(queryOperation),
persistedExchange({ preferGetForPersistedQueries: preferGetMethodValue })(
exchangeArgs
),
take(1),
toPromise
);

expect(res.operation.context.preferGetMethod).toBe(preferGetMethodValue);
}
);
22 changes: 14 additions & 8 deletions exchanges/persisted/src/persistedExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
CombinedError,
Exchange,
Operation,
OperationContext,
} from '@urql/core';

import { hash } from './sha256';
Expand All @@ -29,19 +30,23 @@ const isPersistedUnsupported = (error: CombinedError): boolean =>

/** Input parameters for the {@link persistedExchange}. */
export interface PersistedExchangeOptions {
/** Enforces GET method requests to be made for Persisted Queries.
/** Controls whether GET method requests will be made for Persisted Queries.
*
* @remarks
* When enabled, the `persistedExchange` will set
* When set to `true` or `'within-url-limit'`, the `persistedExchange`
* will use GET requests on persisted queries when the request URL
* doesn't exceed the 2048 character limit.
*
* When set to `force`, the `persistedExchange` will set
* `OperationContext.preferGetMethod` to `'force'` on persisted queries,
* which will force requests to be made using a GET request.
*
* This is frequently used to make GraphQL requests more cacheable
* on CDNs.
* GET requests are frequently used to make GraphQL requests more
* cacheable on CDNs.
*
* @defaultValue `true` - enabled
* @defaultValue `undefined` - disabled
*/
preferGetForPersistedQueries?: boolean;
preferGetForPersistedQueries?: OperationContext['preferGetMethod'];
/** Enforces non-automatic persisted queries by ignoring APQ errors.
*
* @remarks
Expand Down Expand Up @@ -118,7 +123,7 @@ export const persistedExchange =
({ forward }) => {
if (!options) options = {};

const preferGetForPersistedQueries = !!options.preferGetForPersistedQueries;
const preferGetForPersistedQueries = options.preferGetForPersistedQueries;
const enforcePersistedQueries = !!options.enforcePersistedQueries;
const hashFn = options.generateHash || hash;
const enableForMutation = !!options.enableForMutation;
Expand Down Expand Up @@ -163,7 +168,8 @@ export const persistedExchange =
persistedOperation.kind === 'query' &&
preferGetForPersistedQueries
) {
persistedOperation.context.preferGetMethod = 'force';
persistedOperation.context.preferGetMethod =
preferGetForPersistedQueries;
}
}

Expand Down

0 comments on commit 9d793b2

Please sign in to comment.