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.