Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1--- 2title: '@urql/core' 3order: 0 4--- 5 6# @urql/core 7 8> **Note:** These API docs are deprecated as we now keep TSDocs in all published packages. 9> You can view TSDocs while using these packages in your editor, as long as it supports the 10> TypeScript Language Server. 11> We're planning to replace these API docs with a separate web app soon. 12 13The `@urql/core` package is the basis of all framework bindings. Each bindings-package, 14like [`urql` for React](./urql.md) or [`@urql/preact`](./preact.md), will reuse the core logic and 15reexport all exports from `@urql/core`. 16Therefore if you're not accessing utilities directly, aren't in a Node.js environment, and are using 17framework bindings, you'll likely want to import from your framework bindings package directly. 18 19[Read more about `urql`'s core on the "Core Package" page.](../basics/core.md) 20 21## Client 22 23The `Client` manages all operations and ongoing requests to the exchange pipeline. 24It accepts several options on creation. 25 26`@urql/core` also exposes `createClient()` that is just a convenient alternative to calling `new Client()`. 27 28| Input | Type | Description | 29| ----------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 30| `exchanges` | `Exchange[]` | An array of `Exchange`s that the client should use | 31| `url` | `string` | The GraphQL API URL as used by `fetchExchange` | 32| `fetchOptions` | `RequestInit \| () => RequestInit` | Additional `fetchOptions` that `fetch` in `fetchExchange` should use to make a request | 33| `fetch` | `typeof fetch` | An alternative implementation of `fetch` that will be used by the `fetchExchange` instead of `window.fetch` | 34| `suspense` | `?boolean` | Activates the experimental React suspense mode, which can be used during server-side rendering to prefetch data | 35| `requestPolicy` | `?RequestPolicy` | Changes the default request policy that will be used. By default, this will be `cache-first`. | 36| `preferGetMethod` | `?boolean \| 'force' \| 'within-url-limit'` | This is picked up by the `fetchExchange` and will force all queries (not mutations) to be sent using the HTTP GET method instead of POST if the length of the resulting URL doesn't exceed 2048 characters. When `'force'` is passed a GET request is always sent regardless of how long the resulting URL is. | 37 38### client.executeQuery 39 40Accepts a [`GraphQLRequest`](#graphqlrequest) and optionally `Partial<OperationContext>`, and returns a 41[`Source<OperationResult>`](#operationresult) — a stream of query results that can be subscribed to. 42 43Internally, subscribing to the returned source will create an [`Operation`](#operation), with 44`kind` set to `'query'`, and dispatch it on the 45exchanges pipeline. If no subscribers are listening to this operation anymore and unsubscribe from 46the query sources, the `Client` will dispatch a "teardown" operation. 47 48- [Instead of using this method directly, you may want to use the `client.query` shortcut 49 instead.](#clientquery) 50- [See `createRequest` for a utility that creates `GraphQLRequest` objects.](#createrequest) 51 52### client.executeSubscription 53 54This is functionally the same as `client.executeQuery`, but creates operations for subscriptions 55instead, with `kind` set to `'subscription'`. 56 57### client.executeMutation 58 59This is functionally the same as `client.executeQuery`, but creates operations for mutations 60instead, with `kind` set to `'mutation'`. 61 62A mutation source is always guaranteed to only respond with a single [`OperationResult`](#operationresult) and then complete. 63 64### client.query 65 66This is a shorthand method for [`client.executeQuery`](#clientexecutequery), which accepts a query 67(`DocumentNode | string`) and variables separately and creates a [`GraphQLRequest`](#graphqlrequest) [`createRequest`](#createrequest) automatically. 68 69The returned `Source<OperationResult>` will also have an added `toPromise` method, so the stream can 70be conveniently converted to a promise. 71 72```js 73import { pipe, subscribe } from 'wonka'; 74 75const { unsubscribe } = pipe( 76 client.query('{ test }', { 77 /* vars */ 78 }), 79 subscribe(result => { 80 console.log(result); // OperationResult 81 }) 82); 83 84// or with toPromise, which also limits this to one result 85client 86 .query('{ test }', { 87 /* vars */ 88 }) 89 .toPromise() 90 .then(result => { 91 console.log(result); // OperationResult 92 }); 93``` 94 95[Read more about how to use this API on the "Core Package" 96page.](../basics/core.md#one-off-queries-and-mutations) 97 98### client.mutation 99 100This is similar to [`client.query`](#clientquery), but dispatches mutations instead. 101 102[Read more about how to use this API on the "Core Package" 103page.](../basics/core.md#one-off-queries-and-mutations) 104 105### client.subscription 106 107This is similar to [`client.query`](#clientquery), but does not provide a `toPromise()` helper method on the streams it returns. 108 109[Read more about how to use this API on the "Subscriptions" page.](../advanced/subscriptions.md) 110 111### client.reexecuteOperation 112 113This method is commonly used in _Exchanges_ to reexecute an [`Operation`](#operation) on the 114`Client`. It will only reexecute when there are still subscribers for the given 115[`Operation`](#operation). 116 117For an example, this method is used by the `cacheExchange` when an 118[`OperationResult`](#operationresult) is invalidated in the cache and needs to be refetched. 119 120### client.readQuery 121 122This method is typically used to read data synchronously from a cache. It returns an [`OperationResult`](#operationresult) if a value is returned immediately or `null` if no value is returned while cancelling all side effects. 123 124## CombinedError 125 126The `CombinedError` is used in `urql` to normalize network errors and `GraphQLError`s if anything 127goes wrong during a GraphQL request. 128 129| Input | Type | Description | 130| --------------- | -------------------------------- | ---------------------------------------------------------------------------------- | 131| `networkError` | `?Error` | An unexpected error that might've occurred when trying to send the GraphQL request | 132| `graphQLErrors` | `?Array<string \| GraphQLError>` | GraphQL Errors (if any) that were returned by the GraphQL API | 133| `response` | `?any` | The raw response object (if any) from the `fetch` call | 134 135[Read more about errors in `urql` on the "Error" page.](../basics/errors.md) 136 137## Types 138 139### GraphQLRequest 140 141This often comes up as the **input** for every GraphQL request. 142It consists of `query` and optionally `variables`. 143 144| Prop | Type | Description | 145| ----------- | -------------- | --------------------------------------------------------------------------------------------------------------------- | 146| `key` | `number` | A unique key that identifies this exact combination of `query` and `variables`, which is derived using a stable hash. | 147| `query` | `DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. | 148| `variables` | `?object` | The variables to be used with the GraphQL request. | 149 150The `key` property is a hash of both the `query` and the `variables`, to uniquely 151identify the request. When `variables` are passed it is ensured that they're stably stringified so 152that the same variables in a different order will result in the same `key`, since variables are 153order-independent in GraphQL. 154 155[A `GraphQLRequest` may be manually created using the `createRequest` helper.](#createrequest) 156 157### OperationType 158 159This determines what _kind of operation_ the exchanges need to perform. 160This is one of: 161 162- `'subscription'` 163- `'query'` 164- `'mutation'` 165- `'teardown'` 166 167The `'teardown'` operation is special in that it instructs exchanges to cancel 168any ongoing operations with the same key as the `'teardown'` operation that is 169received. 170 171### Operation 172 173The input for every exchange that informs GraphQL requests. 174It extends the [`GraphQLRequest` type](#graphqlrequest) and contains these additional properties: 175 176| Prop | Type | Description | 177| --------- | ------------------ | --------------------------------------------- | 178| `kind` | `OperationType` | The type of GraphQL operation being executed. | 179| `context` | `OperationContext` | Additional metadata passed to exchange. | 180 181An `Operation` also contains the `operationName` property, which is a deprecated alias of the `kind` 182property and outputs a deprecation warning if it's used. 183 184### RequestPolicy 185 186This determines the strategy that a cache exchange should use to fulfill an operation. 187When you implement a custom cache exchange it's recommended that these policies are 188handled. 189 190- `'cache-first'` (default) 191- `'cache-only'` 192- `'network-only'` 193- `'cache-and-network'` 194 195[Read more about request policies on the "Document Caching" page.](../basics/document-caching.md#request-policies) 196 197### OperationContext 198 199The context often carries options or metadata for individual exchanges, but may also contain custom 200data that can be passed from almost all API methods in `urql` that deal with 201[`Operation`s](#operation). 202 203Some of these options are set when the `Client` is initialised, so in the following list of 204properties you'll likely see some options that exist on the `Client` as well. 205 206| Prop | Type | Description | 207| --------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | 208| `fetchOptions` | `?RequestInit \| (() => RequestInit)` | Additional `fetchOptions` that `fetch` in `fetchExchange` should use to make a request. | 209| `fetch` | `typeof fetch` | An alternative implementation of `fetch` that will be used by the `fetchExchange` instead of `window.fetch` | 210| `requestPolicy` | `RequestPolicy` | An optional [request policy](../basics/document-caching.md#request-policies) that should be used specifying the cache strategy. | 211| `url` | `string` | The GraphQL endpoint, when using GET you should use absolute url's | 212| `meta` | `?OperationDebugMeta` | Metadata that is only available in development for devtools. | 213| `suspense` | `?boolean` | Whether suspense is enabled. | 214| `preferGetMethod` | `?boolean \| 'force' \| 'within-url-limit'` | Instructs the `fetchExchange` to use HTTP GET for queries. | 215| `additionalTypenames` | `?string[]` | Allows you to tell the operation that it depends on certain typenames (used in document-cache.) | 216 217It also accepts additional, untyped parameters that can be used to send more 218information to custom exchanges. 219 220### OperationResult 221 222The result of every GraphQL request, i.e. an `Operation`. It's very similar to what comes back from 223a typical GraphQL API, but slightly enriched and normalized. 224 225| Prop | Type | Description | 226| ------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | 227| `operation` | `Operation` | The operation that this is a result for | 228| `data` | `?any` | Data returned by the specified query | 229| `error` | `?CombinedError` | A [`CombinedError`](#combinederror) instances that wraps network or `GraphQLError`s (if any) | 230| `extensions` | `?Record<string, any>` | Extensions that the GraphQL server may have returned. | 231| `stale` | `?boolean` | A flag that may be set to `true` by exchanges to indicate that the `data` is incomplete or out-of-date, and that the result will be updated soon. | 232 233### ExchangeInput 234 235This is the input that an [`Exchange`](#exchange) receives when it's initialized by the 236[`Client`](#client) 237 238| Input | Type | Description | 239| --------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- | 240| `forward` | `ExchangeIO` | The unction responsible for receiving an observable operation and returning a result | 241| `client` | `Client` | The urql application-wide client library. Each execute method starts a GraphQL request and returns a stream of results. | 242 243### Exchange 244 245An exchange represents abstractions of small chunks of logic in `urql`. 246They're small building blocks and similar to "middleware". 247 248[Read more about _Exchanges_ on the "Authoring Exchanges" page.](../advanced/authoring-exchanges.md) 249 250An exchange is defined to be a function that receives [`ExchangeInput`](#exchangeinput) and returns 251an `ExchangeIO` function. The `ExchangeIO` function in turn will receive a stream of operations, and 252must return a stream of results. If the exchange is purely transforming data, like the 253`mapExchange` for instance, it'll call `forward`, which is the next Exchange's `ExchangeIO` 254function to get a stream of results. 255 256```js 257type ExchangeIO = (Source<Operation>) => Source<OperationResult>; 258type Exchange = ExchangeInput => ExchangeIO; 259``` 260 261[If you haven't yet seen streams you can read more about "Stream Patterns" on the "Architecture" 262page.](../architecture.md) 263 264## Exchanges 265 266### cacheExchange 267 268The `cacheExchange` as [described on the "Document Caching" page.](../basics/document-caching.md). It's of type `Exchange`. 269 270### subscriptionExchange 271 272The `subscriptionExchange` as [described on the "Subscriptions" page.](../advanced/subscriptions.md). It's of type `Options => Exchange`. 273 274It accepts a single input: `{ forwardSubscription }`. This is a function that 275receives an enriched operation and must return an Observable-like object that 276streams `GraphQLResult`s with `data` and `errors`. 277 278The `forwardSubscription` function is commonly connected to the [`subscriptions-transport-ws` 279package](https://github.com/apollographql/subscriptions-transport-ws). 280 281### ssrExchange 282 283The `ssrExchange` as [described on the "Server-side Rendering" 284page.](../advanced/server-side-rendering.md). 285It's of type `Options => Exchange`. 286 287It accepts three inputs, `initialState` which is completely 288optional and populates the server-side rendered data with 289a rehydrated cache, `isClient` which can be set to 290`true` or `false` to tell the `ssrExchange` whether to 291write to (server-side) or read from (client-side) the cache, and 292`staleWhileRevalidate` which will treat rehydrated data as stale 293and refetch up-to-date data by reexecuring the operation using a `network-only` requests policy. 294 295By default, `isClient` defaults to `true` when the `Client.suspense` 296mode is disabled and to `false` when the `Client.suspense` mode 297is enabled. 298 299This can be used to extract data that has been queried on 300the server-side, which is also described in the Basics section, 301and is also used on the client-side to restore server-side 302rendered data. 303 304When called, this function creates an `Exchange`, which also has 305two methods on it: 306 307- `.restoreData(data)` which can be used to inject data, typically 308 on the client-side. 309- `.extractData()` which is typically used on the server-side to 310 extract the server-side rendered data. 311 312Basically, the `ssrExchange` is a small cache that collects data 313during the server-side rendering pass, and allows you to populate 314the cache on the client-side with the same data. 315 316During React rehydration this cache will be emptied, and it will 317become inactive and won't change the results of queries after 318rehydration. 319 320It needs to be used _after_ other caching Exchanges like the 321`cacheExchange`, but before any _asynchronous_ Exchange like 322the `fetchExchange`. 323 324### debugExchange 325 326An exchange that writes incoming `Operation`s to `console.log` and 327writes completed `OperationResult`s to `console.log`. 328 329This exchange is disabled in production and is based on the `mapExchange`. 330If you'd like to customise it, you can replace it with a custom `mapExchange`. 331 332### fetchExchange 333 334The `fetchExchange` of type `Exchange` is responsible for sending operations of type `'query'` and 335`'mutation'` to a GraphQL API using `fetch`. 336 337### mapExchange 338 339The `mapExchange` allows you to: 340 341- react to or replace operations with `onOperation`, 342- react to or replace results with `onResult`, 343- and; react to errors in results with `onError`. 344 345It can therefore be used to quickly react to the core events in the `Client` without writing a custom 346exchange, effectively allowing you to ship your own `debugExchange`. 347 348```ts 349mapExchange({ 350 onOperation(operation) { 351 console.log('operation', operation); 352 }, 353 onResult(result) { 354 console.log('result', result); 355 }, 356}); 357``` 358 359It can also be used to react only to errors, which is the same as checking for `result.error`: 360 361```ts 362mapExchange({ 363 onError(error, operation) { 364 console.log(`The operation ${operation.key} has errored with:`, error); 365 }, 366}); 367``` 368 369Lastly, it can be used to map operations and results, which may be useful to update the 370`OperationContext` or perform other standard tasks that require you to wait for a result: 371 372```ts 373import { mapExchange, makeOperation } from '@urql/core'; 374 375mapExchange({ 376 async onOperation(operation) { 377 // NOTE: This is only for illustration purposes 378 return makeOperation(operation.kind, operation, { 379 ...operation.context, 380 test: true, 381 }); 382 }, 383 async onResult(result) { 384 // NOTE: This is only for illustration purposes 385 if (result.data === undefined) result.data = null; 386 return result; 387 }, 388}); 389``` 390 391### errorExchange (deprecated) 392 393An exchange that lets you inspect errors. This can be useful for logging, or reacting to 394different types of errors (e.g. logging the user out in case of a permission error). 395 396In newer versions of `@urql/core`, it's identical to the `mapExchange` and its export has been 397replaced as the `mapExchange` also allows you to pass an `onError` function. 398 399## Utilities 400 401### gql 402 403This is a `gql` tagged template literal function, similar to the one that's also commonly known from 404`graphql-tag`. It can be used to write GraphQL documents in a tagged template literal and returns a 405parsed `DocumentNode` that's primed against the `createRequest`'s cache for `key`s. 406 407```js 408import { gql } from '@urql/core'; 409 410const SharedFragment = gql` 411 fragment UserFrag on User { 412 id 413 name 414 } 415`; 416 417gql` 418 query { 419 user 420 ...UserFrag 421 } 422 423 ${SharedFragment} 424`; 425``` 426 427Unlike `graphql-tag`, this function outputs a warning in development when names of fragments in the 428document are duplicated. It does not output warnings when fragment names were duplicated globally 429however. 430 431### stringifyVariables 432 433This function is a variation of `JSON.stringify` that sorts any object's keys that is being 434stringified to ensure that two objects with a different order of keys will be stably stringified to 435the same string. 436 437```js 438stringifyVariables({ a: 1, b: 2 }); // {"a":1,"b":2} 439stringifyVariables({ b: 2, a: 1 }); // {"a":1,"b":2} 440``` 441 442### createRequest 443 444This utility accepts a GraphQL query of type `string | DocumentNode` and optionally an object of 445variables, and returns a [`GraphQLRequest` object](#graphqlrequest). 446 447Since the [`client.executeQuery`](#clientexecutequery) and other execute methods only accept 448[`GraphQLRequest`s](#graphqlrequest), this helper is commonly used to create that request first. The 449[`client.query`](#clientquery) and [`client.mutation`](#clientmutation) methods use this helper as 450well to create requests. 451 452The helper takes care of creating a unique `key` for the `GraphQLRequest`. This is a hash of the 453`query` and `variables` if they're passed. The `variables` will be stringified using 454[`stringifyVariables`](#stringifyvariables), which outputs a stable JSON string. 455 456Additionally, this utility will ensure that the `query` reference will remain stable. This means 457that if the same `query` will be passed in as a string or as a fresh `DocumentNode`, then the output 458will always have the same `DocumentNode` reference. 459 460### makeOperation 461 462This utility is used to either turn a [`GraphQLRequest` object](#graphqlrequest) into a new 463[`Operation` object](#operation) or to copy an `Operation`. It adds the `kind` property, and the 464`operationName` alias that outputs a deprecation warning. 465 466It accepts three arguments: 467 468- An `Operation`'s `kind` (See [`OperationType`](#operationtype) 469- A [`GraphQLRequest` object](#graphqlrequest) or another [`Operation`](#operation) that should be 470 copied. 471- and; optionally a [partial `OperationContext` object.](#operationcontext). This argument may be 472 left out if the context is to be copied from the operation that may be passed as a second argument. 473 474Hence some valid uses of the utility are: 475 476```js 477// Create a new operation from scratch 478makeOperation('query', createRequest(query, variables), client.createOperationContext(opts)); 479 480// Turn an operation into a 'teardown' operation 481makeOperation('teardown', operation); 482 483// Copy an existing operation while modifying its context 484makeOperation(operation.kind, operation, { 485 ...operation.context, 486 preferGetMethod: true, 487}); 488``` 489 490### makeResult 491 492This is a helper function that converts a GraphQL API result to an 493[`OperationResult`](#operationresult). 494 495It accepts an [`Operation`](#operation), the API result, and optionally the original `FetchResponse` 496for debugging as arguments, in that order. 497 498### makeErrorResult 499 500This is a helper function that creates an [`OperationResult`](#operationresult) for GraphQL API 501requests that failed with a generic or network error. 502 503It accepts an [`Operation`](#operation), the error, and optionally the original `FetchResponse` 504for debugging as arguments, in that order. 505 506### formatDocument 507 508This utility is used by the [`cacheExchange`](#cacheexchange) and by 509[Graphcache](../graphcache/README.md) to add `__typename` fields to GraphQL `DocumentNode`s. 510 511### composeExchanges 512 513This utility accepts an array of `Exchange`s and composes them into a single one. 514It chains them in the order that they're given, left to right. 515 516```js 517function composeExchanges(Exchange[]): Exchange; 518``` 519 520This can be used to combine some exchanges and is also used by [`Client`](#client) 521to handle the `exchanges` input.