Skip to content

Commit

Permalink
Merge branch 'main' into issue-10105-loading-stays-true
Browse files Browse the repository at this point in the history
  • Loading branch information
alessbell authored Oct 12, 2022
2 parents fef5de6 + c915214 commit 94a73f1
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 125 deletions.
33 changes: 18 additions & 15 deletions docs/source/api/link/apollo-link-rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ description: Call REST APIs inside your GraphQL queries.

## Overview

> The [Apollo Link Rest](https://github.com/apollographql/apollo-link-rest) library is maintained by Apollo community members and not an Apollo GraphQL maintained library.
Calling REST APIs from a GraphQL client opens the benefits of GraphQL for more people, whether:

* You are in a front-end developer team that wants to try GraphQL without asking for the backend team to implement a GraphQL server.
Expand All @@ -14,7 +16,7 @@ Calling REST APIs from a GraphQL client opens the benefits of GraphQL for more p

With `apollo-link-rest`, you can call your endpoints inside your GraphQL queries and have all your data managed by Apollo Client. `apollo-link-rest` is suitable for just dipping your toes in the water, or doing a full-steam ahead integration, and then later on migrating to a backend-driven GraphQL experience.

> For more advanced or complex back-ends, you may want to consider using [`apollo-server`](/apollo-server/).
> For more advanced or complex back-ends, you may want to consider using [`@apollo/server`](/apollo-server/).
## Quick start

Expand Down Expand Up @@ -69,17 +71,17 @@ The `RestLink` constructor accepts an options object that can be used to customi

| Option | Type | Description |
| - | - | - |
| `uri` | `string` | The URI key is a string endpoint/domain for your requests to hit (_optional_ when `endpoints` provides a default) |
| `endpoints: /map-of-endpoints/` | `any` | _optional_ A map of endpoints. If you use this, you need to provide `endpoint` to the `@rest(...)` directives. |
| `customFetch?` | `any` | _optional_ A custom `fetch` to handle `REST` calls |
| `headers?` | `Headers` | _optional_ An object representing values to be sent as headers with all requests. [Documented here](https://developer.mozilla.org/en-US/docs/Web/API/Request/headers) |
| `credentials?` | `string` | _optional_ A string representing the credentials policy the fetch call should operate with. [Document here](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials) |
| `fieldNameNormalizer?: /function/` | `any` | _optional_ A function that takes the response field name and converts it into a GraphQL compliant name. This is useful if your `REST` API returns fields that aren't representable as GraphQL, or if you want to convert between `snake_case` field names in JSON to `camelCase` keyed fields. |
| `fieldNameDenormalizer?: /function/` | `any` | _optional_ A function that takes a GraphQL-compliant field name and converts it back into an endpoint-specific name. |
| `typePatcher: /map-of-functions/` | `any` | _optional_ A structure to allow you to specify the `__typename` when you have nested objects in your REST response. |
| `defaultSerializer /function/` | `any` | _optional_ A function that will be used by the `RestLink` as the default serializer when no `bodySerializer` is defined for a `@rest` call. The function will also be passed the current `Header` set, which can be updated before the request is sent to `fetch`. Default method uses `JSON.stringify` and sets the `Content-Type` to `application/json`. |
| `bodySerializers: /map-of-functions/` | `any` | _optional_ Structure to allow the definition of alternative serializers, which can then be specified by their key. |
| `responseTransformer?: /function/` | `any` | _optional_ Apollo expects a record response to return a root object, and a collection of records response to return an array of objects. Use this function to structure the response into the format Apollo expects if your response data is structured differently. |
| `uri` | `string` | The URI key is a string endpoint/domain for your requests to hit (*optional* when `endpoints` provides a default) |
| `endpoints: /map-of-endpoints/` | `any` | *optional* A map of endpoints. If you use this, you need to provide `endpoint` to the `@rest(...)` directives. |
| `customFetch?` | `any` | *optional* A custom `fetch` to handle `REST` calls |
| `headers?` | `Headers` | *optional* An object representing values to be sent as headers with all requests. [Documented here](https://developer.mozilla.org/en-US/docs/Web/API/Request/headers) |
| `credentials?` | `string` | *optional* A string representing the credentials policy the fetch call should operate with. [Document here](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials) |
| `fieldNameNormalizer?: /function/` | `any` | *optional* A function that takes the response field name and converts it into a GraphQL compliant name. This is useful if your `REST` API returns fields that aren't representable as GraphQL, or if you want to convert between `snake_case` field names in JSON to `camelCase` keyed fields. |
| `fieldNameDenormalizer?: /function/` | `any` | *optional* A function that takes a GraphQL-compliant field name and converts it back into an endpoint-specific name. |
| `typePatcher: /map-of-functions/` | `any` | *optional* A structure to allow you to specify the `__typename` when you have nested objects in your REST response. |
| `defaultSerializer /function/` | `any` | *optional* A function that will be used by the `RestLink` as the default serializer when no `bodySerializer` is defined for a `@rest` call. The function will also be passed the current `Header` set, which can be updated before the request is sent to `fetch`. Default method uses `JSON.stringify` and sets the `Content-Type` to `application/json`. |
| `bodySerializers: /map-of-functions/` | `any` | *optional* Structure to allow the definition of alternative serializers, which can then be specified by their key. |
| `responseTransformer?: /function/` | `any` | *optional* Apollo expects a record response to return a root object, and a collection of records response to return an array of objects. Use this function to structure the response into the format Apollo expects if your response data is structured differently. |

### Multiple endpoints

Expand Down Expand Up @@ -325,7 +327,7 @@ const link = new RestLink({
### Custom Fetch

By default, Apollo uses the browsers `fetch` method to handle `REST` requests to your domain/endpoint. The `customFetch` option allows you to specify _your own_ request handler by defining a function that returns a `Promise` with a fetch-response-like object:
By default, Apollo uses the browsers `fetch` method to handle `REST` requests to your domain/endpoint. The `customFetch` option allows you to specify *your own* request handler by defining a function that returns a `Promise` with a fetch-response-like object:

```js
const link = new RestLink({
Expand All @@ -339,7 +341,7 @@ const link = new RestLink({

To resolve your GraphQL queries quickly, Apollo will issue requests to relevant endpoints as soon as possible. This is generally ok, but can lead to large numbers of `REST` requests to be fired at once; especially for deeply nested queries [(see `@export` directive)](#export-directive).

> Some endpoints (like public APIs) might enforce _rate limits_, leading to failed responses and unresolved queries in such cases.
> Some endpoints (like public APIs) might enforce *rate limits*, leading to failed responses and unresolved queries in such cases.
By example, `customFetch` is a good place to manage your apps fetch operations. The following implementation makes sure to only issue 2 requests at a time (concurrency) while waiting at least 500ms until the next batch of requests is fired.

Expand All @@ -356,6 +358,7 @@ const link = new RestLink({
),
});
```

> Since Apollo issues `Promise` based requests, we can resolve them as we see fit. This example uses [`pThrottle`](https://github.com/sindresorhus/p-throttle); part of the popular [promise-fun](https://github.com/sindresorhus/promise-fun) collection.
### Complete options
Expand Down Expand Up @@ -646,7 +649,7 @@ const restLink = new RestLink({

The export directive re-exposes a field for use in a later (nested) query. These are the same semantics that will be supported on the server, but when used in a `RestLink` you can use the exported variables for further calls (i.e. waterfall requests from nested fields).

_Note: If you're constantly using @export you may prefer to take a look at [`apollo-server`](/apollo-server/)._
_Note: If you're constantly using @export you may prefer to take a look at [`@apollo/server`](/apollo-server/)._

### Arguments

Expand Down
8 changes: 4 additions & 4 deletions docs/source/caching/advanced-topics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You can persist and rehydrate the `InMemoryCache` from a storage provider like `

To get started, pass your cache and a storage provider to `persistCache`. By default, the contents of your cache are immediately restored asynchronously, and they're persisted on every write to the cache with a short configurable debounce interval.

> Note: The `persistCache` method is async and returns a `Promise`.
> **Note:** The `persistCache` method is async and returns a `Promise`.
```js
import { AsyncStorage } from 'react-native';
Expand Down Expand Up @@ -245,11 +245,11 @@ For details, see [The `fetchMore` function](../pagination/core-api/#the-fetchmor
### The `@connection` directive
Fundamentally, paginated queries are the same as any other query with the exception that calls to `fetchMore` update the same cache key. Since these queries are cached by both the initial query and their parameters, a problem arises when later retrieving or updating paginated queries in the cache. We dont care about pagination arguments such as limits, offsets, or cursors outside of the need to `fetchMore`, nor do we want to provide them simply for accessing cached data.
Fundamentally, paginated queries are the same as any other query with the exception that calls to `fetchMore` update the same cache key. Because these queries are cached by both the initial query and their parameters, a problem arises when later retrieving or updating paginated queries in the cache. We don't care about pagination arguments such as limits, offsets, or cursors outside of the need to `fetchMore`, nor do we want to provide them simply for accessing cached data.
To solve this Apollo Client 1.6 introduced the `@connection` directive to specify a custom store key for results. A connection allows us to set the cache key for a field and to filter which arguments actually alter the query.
To solve this, you can use the `@connection` directive to specify a custom cache key for results. A connection allows us to set the cache key for a field and to filter which arguments actually alter the query.
To use the `@connection` directive, simply add the directive to the segment of the query you want a custom store key for and provide the `key` parameter to specify the store key. In addition to the `key` parameter, you can also include the optional `filter` parameter, which takes an array of query argument names to include in the generated custom store key.
To use the `@connection` directive, add it to the segment of the query you want a custom store key for and provide the `key` parameter to specify the store key. In addition to the `key` parameter, you can also include the optional `filter` parameter, which takes an array of query argument names to include in the generated custom store key.
```js
const query = gql`
Expand Down
15 changes: 7 additions & 8 deletions docs/source/caching/cache-configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ title: Configuring the Apollo Client cache

This article describes cache setup and configuration. To learn how to interact with cached data, see [Reading and writing data to the cache](./cache-interaction).

## Installation

In Apollo Client 3, the `InMemoryCache` class is provided by the `@apollo/client` package. No additional libraries are required.

## Initialization

Create an `InMemoryCache` object and provide it to the `ApolloClient` constructor, like so:
Expand Down Expand Up @@ -54,7 +50,9 @@ To customize cache behavior, you provide a configuration object to the `InMemory
</td>
<td>

If `true`, the cache automatically adds `__typename` fields to all objects in outgoing queries, removing the need to add them manually.
If `true`, the cache automatically requests the `__typename` field for every object in your outgoing operations, which means you can omit `__typename` from your operation definitions.

By default, the cache uses the `__typename` field as part of the cache ID for every cached object, so it's helpful to guarantee that the field is always fetched.

The default value is `true`.

Expand Down Expand Up @@ -126,6 +124,8 @@ Each key in the object is the `__typename` of a type to customize, and the corre

A function that takes a response object and returns a unique identifier to be used when normalizing the data in the store.

For details, see [Customizing identifier generation globally](#customizing-identifier-generation-globally).

</td>
</tr>
</tbody>
Expand Down Expand Up @@ -180,7 +180,7 @@ This example shows a variety of `typePolicies` with different `keyFields`:

If an object has multiple `keyFields`, the cache ID always lists those fields in the same order to ensure uniqueness.

Note that these `keyFields` strings always refer to the actual field names as defined in your schema, meaning the ID computation is not sensitive to [field aliases](/resources/graphql-glossary/#alias).
Note that these `keyFields` strings always refer to the canonical field names defined in the schema. This means that ID computation is _not_ sensitive to [field aliases](/resources/graphql-glossary/#alias).

### Calculating an object's cache ID

Expand Down Expand Up @@ -306,11 +306,10 @@ const equivalentResult = cache.readQuery({
});
```

The cache normally obtains `__typename` information by adding the `__typename` field to every query selection set it sends to the server. It could technically use this same method for the outermost selection set of every operation, but the `__typename`s of the root query and mutation are almost always `"Query"` and `"Mutation"`, so the cache assumes those common defaults unless instructed otherwise in a `TypePolicy`.
The cache usually obtains `__typename` information by adding the `__typename` field to every query selection set it sends to the server. It could technically use this same method for the outermost selection set of every operation, but the `__typename`s of the root query and mutation are almost always `"Query"` and `"Mutation"`, so the cache assumes those common defaults unless instructed otherwise in a `TypePolicy`.

For most objects in a graph, the `__typename` field is vital for proper identification and normalization. For the root query and mutation types, the `__typename` is not nearly as useful or important, because those types are singletons with only one instance per client.

### The `fields` property

The final property within `TypePolicy` is the `fields` property, which enables you to [customize the behavior of individual cached fields](./cache-field-behavior).

Loading

0 comments on commit 94a73f1

Please sign in to comment.