···11<div align="center">
22- <img width="540" alt="urql" src="https://raw.githubusercontent.com/FormidableLabs/urql/master/docs/urql-banner.gif" />
22+ <img alt="urql" width="250" src="docs/assets/urql-logo.png" />
3344 <br />
55 <br />
···9090Internally, `urql` will create a unique `key` for any operation it starts which is a hash of `query` and
9191`variables`. The internal "Exchange pipeline" is then responsible for fulfilling the operation.
92929393-<img width="606" src="docs/urql-operation-keys.png" alt="Diagram: An Operation key is computed by hashing the combination of the stringified query and the stabily stringified variables. DocumentNodes may either be stringified fully or just by using their operation names. Properties of any variables object need to be stabily sorted." />
9393+<img width="606" src="docs/assets/urql-operation-keys.png" alt="Diagram: An Operation key is computed by hashing the combination of the stringified query and the stabily stringified variables. DocumentNodes may either be stringified fully or just by using their operation names. Properties of any variables object need to be stabily sorted." />
94949595The result's error is a [`CombinedError`](https://formidable.com/open-source/urql/docs/api/#combinederror-class), which
9696normalises GraphQL errors and Network errors by combining them into one wrapping class.
97979898-<img width="693" src="docs/urql-combined-error.png" alt="Diagram: A CombinedError has two states. It can either have a property 'networkError', or it can have multiple, rehydrated GraphQL errors on the 'graphQLErrors' property. The message of the CombinedError will always be a summary of the errors it contains." />
9898+<img width="693" src="docs/assets/urql-combined-error.png" alt="Diagram: A CombinedError has two states. It can either have a property 'networkError', or it can have multiple, rehydrated GraphQL errors on the 'graphQLErrors' property. The message of the CombinedError will always be a summary of the errors it contains." />
9999100100[Learn more about `useQuery` in the Getting Started guide](https://formidable.com/open-source/urql/docs/getting-started/#writing-queries)
101101···196196In `urql` all operations are controlled by a central [`Client`](https://formidable.com/open-source/urql/docs/api/#client-class).
197197This client is responsible for managing GraphQL operations and sending requests.
198198199199-<img width="787" src="docs/urql-client-architecture.png" alt="Diagram: The Client is an event hub on which operations may be dispatched by hooks. This creates an input stream (displayed as operations A, B, and C). Each Operation Result that then comes back from the client corresponds to one operation that has been sent to the client. This is the output stream of results (displayed as results A, B, and C)" />
199199+<img width="787" src="docs/assets/urql-client-architecture.png" alt="Diagram: The Client is an event hub on which operations may be dispatched by hooks. This creates an input stream (displayed as operations A, B, and C). Each Operation Result that then comes back from the client corresponds to one operation that has been sent to the client. This is the output stream of results (displayed as results A, B, and C)" />
200200201201Any hook in `urql` dispatches its operation on the client (A, B, C) which will be handled by the client on a
202202single stream of inputs. As responses come back from the cache or your GraphQL API one or more results are
203203dispatched on an output stream that correspond to the operations, which update the hooks.
204204205205-<img width="709" src="docs/urql-event-hub.png" alt="Diagram: The 'useQuery' hook dispatches an operation on the client when it mounts or updates. When it unmounts it dispatches a 'teardown' operation that cancels the original operation. Results that come back from the client update the hook and are filtered by the operation's original key."/>
205205+<img width="709" src="docs/assets/urql-event-hub.png" alt="Diagram: The 'useQuery' hook dispatches an operation on the client when it mounts or updates. When it unmounts it dispatches a 'teardown' operation that cancels the original operation. Results that come back from the client update the hook and are filtered by the operation's original key."/>
206206207207Hence the client can be seen as an event hub. Operations are sent to the client, which executes them and
208208sends back a result. A special teardown-event is issued when a hook unmounts or updates to a different
209209operation.
210210211211-<img width="700" src="docs/urql-signals.png" alt="Diagram: Operations can be seen as signals. Operations with an 'operationName' of query, mutation, or subscription start a query of the given DocumentNode operation. The same operation with an 'operationName' of 'teardown' instructs the client to stop or cancel an ongoing operation of the same key. Operation Results carry the original operation on an 'operation' property, which means they can be identified by reading the key of this operation."/>
211211+<img width="700" src="docs/assets/urql-signals.png" alt="Diagram: Operations can be seen as signals. Operations with an 'operationName' of query, mutation, or subscription start a query of the given DocumentNode operation. The same operation with an 'operationName' of 'teardown' instructs the client to stop or cancel an ongoing operation of the same key. Operation Results carry the original operation on an 'operation' property, which means they can be identified by reading the key of this operation."/>
212212213213[Learn more about the shape of operations and results in our Architecture section!](https://formidable.com/open-source/urql/docs/architecture/)
214214···223223Instead _Exchanges_ are nested and deal with two streams, the input stream of operations and the output stream of results,
224224where the stream of operations go through a pipeline like an intersection in an arbitrary order.
225225226226-<img width="634" src="docs/urql-exchanges.png" alt="Diagram: By default the client has three exchanges. Operations flow through a 'dedup', 'cache', and 'fetch' exchange in this exact order. Their results are flowing backwards through this same chain of exchanges. The 'dedupExchange' deduplicates ongoing operations by their key. The 'cacheExchange' caches results and retrieves them by the operations' keys. The 'fetchExchange' sends operations to a GraphQL API and supports cancellation." />
226226+<img width="634" src="docs/assets/urql-exchanges.png" alt="Diagram: By default the client has three exchanges. Operations flow through a 'dedup', 'cache', and 'fetch' exchange in this exact order. Their results are flowing backwards through this same chain of exchanges. The 'dedupExchange' deduplicates ongoing operations by their key. The 'cacheExchange' caches results and retrieves them by the operations' keys. The 'fetchExchange' sends operations to a GraphQL API and supports cancellation." />
227227228228By default there are three exchanges. The `dedupExchange` deduplicates operations with the same key, the
229229cache exchange handles caching and has a "document" strategy by default, and the `fetchExchange` is typically
···243243These results are aggressively invalidated. Whenever you send a mutation, each result that contains `__typename`s
244244that also occur in the mutation result is invalidated.
245245246246-<img width="736" src="docs/urql-document-caching.png" alt="Diagram: First, a query is made that gets a type, in this example a 'Book'. The result contains the '__typename' field that says 'Book'. This is stored in a mapping of all types to the operations that contained this type. Later a mutation may change some data and will have overlapping types, in this example a 'Book' is liked. The mutation also contains a 'Book' so it retrieves the original operation that was getting a 'Book' and reexecutes and invalidates it." />
246246+<img width="736" src="docs/assets/urql-document-caching.png" alt="Diagram: First, a query is made that gets a type, in this example a 'Book'. The result contains the '__typename' field that says 'Book'. This is stored in a mapping of all types to the operations that contained this type. Later a mutation may change some data and will have overlapping types, in this example a 'Book' is liked. The mutation also contains a 'Book' so it retrieves the original operation that was getting a 'Book' and reexecutes and invalidates it." />
247247248248### Normalized Caching
249249···251251package. The normalized cache is a cache that stores every separate entity in a big graph. Therefore multiple separate queries, subscriptions, and mutations
252252can update each other, if they contain overlapping data with the same type and ID.
253253254254-<img width="466" src="docs/urql-normalized-cache.png" alt="Diagram: A normalized cache contains a graph of different nodes. Queries point to different nodes, which point to other nodes, and so on and so forth. Nodes may be reused and are called 'entities'. Each entity corresponds to an object that came back from the API." />
254254+<img width="466" src="docs/assets/urql-normalized-cache.png" alt="Diagram: A normalized cache contains a graph of different nodes. Queries point to different nodes, which point to other nodes, and so on and so forth. Nodes may be reused and are called 'entities'. Each entity corresponds to an object that came back from the API." />
255255256256Getting started with Graphcache is easy and is as simple as installing it and adding it to your client.
257257Afterwards it comes with a lot of ways to configure it so that less requests need to be sent to your API.
···373373374374**Active:** Formidable is actively working on this project, and we expect to continue for work for the foreseeable future. Bug reports, feature requests and pull requests are welcome.
375375376376-<img width="100%" src="docs/urql-spoiler.png" />
376376+<img width="100%" src="docs/assets/urql-spoiler.png" />