Skip to content

Commit

Permalink
(persisted) - Add enforcePersistedQueries option to persistedFetchExc…
Browse files Browse the repository at this point in the history
…hange (#1358)
  • Loading branch information
kitten authored Feb 3, 2021
1 parent 4df11e0 commit 77fe772
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 26 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-squids-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@urql/exchange-persisted-fetch': minor
---

Add `enforcePersistedQueries` option to `persistedFetchExchange`, which disables automatic persisted queries and retry logic, and instead assumes that persisted queries will be handled like normal GraphQL requests.
5 changes: 5 additions & 0 deletions docs/advanced/persistence-and-uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ persistedFetchExchange({
});
```

Additionally, if the API only expects persisted queries and not arbitrary ones and all queries are
pre-registered against the API then the `persistedFetchExchange` may be put into a **non-automatic**
persisted queries mode by giving it the `enforcePersistedQueries: true` option. This disables any
retry logic and assumes that persisted queries will be handled like regular GraphQL requests.

[Read more about `@urql/persisted-fetch-exchange` in our API
docs.](../api/persisted-fetch-exchange.md)

Expand Down
1 change: 1 addition & 0 deletions docs/api/persisted-fetch-exchange.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ const client = createClient({
| Option | Description |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `preferGetForPersistedQueries` | This is similar to [the `Client`'s `preferGetMethod` option](./core.md#client) and will cause all persisted queries to be sent using a GET request. |
| `enforcePersistedQueries` | This option enforced persisted queries. Instead of allowing automatic persisted queries or triggering any retry logic when the API responds, it instead assumes that persisted queries will succeed and run like normal GraphQL API requests. |
| `generateHash` | This option accepts a function that receives the `query` as a string and the raw `DocumentNode` as a second argument and must return a `Promise<string>` resolving to a SHA256 hash. This can be used to swap out the SHA256 API, e.g. for React Native, or to use pre-generated SHA256 strings from the `DocumentNode`. |
5 changes: 4 additions & 1 deletion exchanges/persisted-fetch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ const client = createClient({
});
```

The `persistedQueryExchange` supports two configuration options:
The `persistedQueryExchange` supports three configuration options:

- `preferGetForPersistedQueries`: Use `GET` for fetches with persisted queries
- `enforcePersistedQueries`: This disables _automatic persisted queries_ and disables any retry
logic for how the API responds to persisted queries. Instead it's assumed that they'll always
succeed.
- `generateHash`: A function that takes a GraphQL query and returns the hashed result. This defaults to the `window.crypto` API in the browser and the `crypto` module in node.

The `persistedFetchExchange` only handles queries, so for mutations we keep the
Expand Down
52 changes: 27 additions & 25 deletions exchanges/persisted-fetch/src/persistedFetchExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { hash } from './sha256';

interface PersistedFetchExchangeOptions {
preferGetForPersistedQueries?: boolean;
enforcePersistedQueries?: boolean;
generateHash?: (query: string, document: DocumentNode) => Promise<string>;
}

Expand All @@ -42,6 +43,8 @@ export const persistedFetchExchange = (
): Exchange => ({ forward, dispatchDebug }) => {
if (!options) options = {};

const preferGetForPersistedQueries = !!options.preferGetForPersistedQueries;
const enforcePersistedQueries = !!options.enforcePersistedQueries;
const hashFn = options.generateHash || hash;
let supportsPersistedQueries = true;

Expand Down Expand Up @@ -87,34 +90,33 @@ export const persistedFetchExchange = (
operation,
body,
dispatchDebug,
!!(
(options as PersistedFetchExchangeOptions)
.preferGetForPersistedQueries && sha256Hash
)
!!(preferGetForPersistedQueries && sha256Hash)
);
}),
mergeMap(result => {
if (result.error && isPersistedUnsupported(result.error)) {
// Reset the body back to its non-persisted state
body.query = query;
body.extensions = undefined;
// Disable future persisted queries
supportsPersistedQueries = false;
return makePersistedFetchSource(
operation,
body,
dispatchDebug,
false
);
} else if (result.error && isPersistedMiss(result.error)) {
// Add query to the body but leave SHA256 hash intact
body.query = query;
return makePersistedFetchSource(
operation,
body,
dispatchDebug,
false
);
if (!enforcePersistedQueries) {
if (result.error && isPersistedUnsupported(result.error)) {
// Reset the body back to its non-persisted state
body.query = query;
body.extensions = undefined;
// Disable future persisted queries if they're not enforced
supportsPersistedQueries = false;
return makePersistedFetchSource(
operation,
body,
dispatchDebug,
false
);
} else if (result.error && isPersistedMiss(result.error)) {
// Add query to the body but leave SHA256 hash intact
body.query = query;
return makePersistedFetchSource(
operation,
body,
dispatchDebug,
false
);
}
}

return fromValue(result);
Expand Down

0 comments on commit 77fe772

Please sign in to comment.