Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

(persisted) - Add enforcePersistedQueries option to persistedFetchExchange (#1358)

authored by

Phil Pluckthun and committed by
GitHub
77fe7725 4df11e0e

+42 -26
+5
.changeset/cuddly-squids-cheat.md
··· 1 + --- 2 + '@urql/exchange-persisted-fetch': minor 3 + --- 4 + 5 + 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
docs/advanced/persistence-and-uploads.md
··· 107 107 }); 108 108 ``` 109 109 110 + Additionally, if the API only expects persisted queries and not arbitrary ones and all queries are 111 + pre-registered against the API then the `persistedFetchExchange` may be put into a **non-automatic** 112 + persisted queries mode by giving it the `enforcePersistedQueries: true` option. This disables any 113 + retry logic and assumes that persisted queries will be handled like regular GraphQL requests. 114 + 110 115 [Read more about `@urql/persisted-fetch-exchange` in our API 111 116 docs.](../api/persisted-fetch-exchange.md) 112 117
+1
docs/api/persisted-fetch-exchange.md
··· 63 63 | Option | Description | 64 64 | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 65 65 | `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. | 66 + | `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. | 66 67 | `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`. |
+4 -1
exchanges/persisted-fetch/README.md
··· 33 33 }); 34 34 ``` 35 35 36 - The `persistedQueryExchange` supports two configuration options: 36 + The `persistedQueryExchange` supports three configuration options: 37 37 38 38 - `preferGetForPersistedQueries`: Use `GET` for fetches with persisted queries 39 + - `enforcePersistedQueries`: This disables _automatic persisted queries_ and disables any retry 40 + logic for how the API responds to persisted queries. Instead it's assumed that they'll always 41 + succeed. 39 42 - `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. 40 43 41 44 The `persistedFetchExchange` only handles queries, so for mutations we keep the
+27 -25
exchanges/persisted-fetch/src/persistedFetchExchange.ts
··· 34 34 35 35 interface PersistedFetchExchangeOptions { 36 36 preferGetForPersistedQueries?: boolean; 37 + enforcePersistedQueries?: boolean; 37 38 generateHash?: (query: string, document: DocumentNode) => Promise<string>; 38 39 } 39 40 ··· 42 43 ): Exchange => ({ forward, dispatchDebug }) => { 43 44 if (!options) options = {}; 44 45 46 + const preferGetForPersistedQueries = !!options.preferGetForPersistedQueries; 47 + const enforcePersistedQueries = !!options.enforcePersistedQueries; 45 48 const hashFn = options.generateHash || hash; 46 49 let supportsPersistedQueries = true; 47 50 ··· 87 90 operation, 88 91 body, 89 92 dispatchDebug, 90 - !!( 91 - (options as PersistedFetchExchangeOptions) 92 - .preferGetForPersistedQueries && sha256Hash 93 - ) 93 + !!(preferGetForPersistedQueries && sha256Hash) 94 94 ); 95 95 }), 96 96 mergeMap(result => { 97 - if (result.error && isPersistedUnsupported(result.error)) { 98 - // Reset the body back to its non-persisted state 99 - body.query = query; 100 - body.extensions = undefined; 101 - // Disable future persisted queries 102 - supportsPersistedQueries = false; 103 - return makePersistedFetchSource( 104 - operation, 105 - body, 106 - dispatchDebug, 107 - false 108 - ); 109 - } else if (result.error && isPersistedMiss(result.error)) { 110 - // Add query to the body but leave SHA256 hash intact 111 - body.query = query; 112 - return makePersistedFetchSource( 113 - operation, 114 - body, 115 - dispatchDebug, 116 - false 117 - ); 97 + if (!enforcePersistedQueries) { 98 + if (result.error && isPersistedUnsupported(result.error)) { 99 + // Reset the body back to its non-persisted state 100 + body.query = query; 101 + body.extensions = undefined; 102 + // Disable future persisted queries if they're not enforced 103 + supportsPersistedQueries = false; 104 + return makePersistedFetchSource( 105 + operation, 106 + body, 107 + dispatchDebug, 108 + false 109 + ); 110 + } else if (result.error && isPersistedMiss(result.error)) { 111 + // Add query to the body but leave SHA256 hash intact 112 + body.query = query; 113 + return makePersistedFetchSource( 114 + operation, 115 + body, 116 + dispatchDebug, 117 + false 118 + ); 119 + } 118 120 } 119 121 120 122 return fromValue(result);