Commit a0661690 authored by Miguel Rincon's avatar Miguel Rincon Committed by Suzanne Selhorn

Document typePolicies and makeVar usage

This change adds information on how to use typePolicies and makeVar to
maintain a local state using Apollo Client 3.
parent c2737699
......@@ -264,9 +264,15 @@ Read more about [Vue Apollo](https://github.com/vuejs/vue-apollo) in the [Vue Ap
### Local state with Apollo
It is possible to manage an application state with Apollo by passing
in a resolvers object when creating the default client. The default state can be set by writing
to the cache after setting up the default client. In the example below, we are using query with `@client` Apollo directive to write the initial data to Apollo cache and then get this state in the Vue component:
It is possible to manage an application state with Apollo by using [client-site resolvers](#using-client-side-resolvers)
or [type policies with reactive variables](#using-type-policies-with-reactive-variables) when creating your default
client.
#### Using client-side resolvers
The default state can be set by writing to the cache after setting up the default client. In the
example below, we are using query with `@client` Apollo directive to write the initial data to
Apollo cache and then get this state in the Vue component:
```javascript
// user.query.graphql
......@@ -322,7 +328,7 @@ export default {
Along with creating local data, we can also extend existing GraphQL types with `@client` fields. This is extremely helpful when we need to mock an API response for fields not yet added to our GraphQL API.
#### Mocking API response with local Apollo cache
##### Mocking API response with local Apollo cache
Using local Apollo Cache is helpful when we have a need to mock some GraphQL API responses, queries, or mutations locally (such as when they're still not added to our actual API).
......@@ -384,6 +390,108 @@ For each attempt to fetch a version, our client fetches `id` and `sha` from the
Read more about local state management with Apollo in the [Vue Apollo documentation](https://vue-apollo.netlify.app/guide/local-state.html#local-state).
#### Using type policies with reactive variables
Apollo Client 3 offers an alternative to [client-side resolvers](#using-client-side-resolvers) by using
[reactive variables to store client state](https://www.apollographql.com/docs/react/local-state/reactive-variables/).
**NOTE:**
We are still learning the best practices for both **type policies** and **reactive vars**.
Take a moment to improve this guide or [leave a comment](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/100)
if you use it!
In the example below we define a `@client` query and its `typedefs`:
```javascript
// ./graphql/typedefs.graphql
extend type Query {
localData: String!
}
```
```javascript
// ./graphql/get_local_data.query.graphql
query getLocalData {
localData @client
}
```
Similar to resolvers, your `typePolicies` will execute when the `@client` query is used. However,
using `makeVar` will trigger every relevant active Apollo query to reactively update when the state
mutates.
```javascript
// ./graphql/local_state.js
import { makeVar } from '@apollo/client/core';
import typeDefs from './typedefs.graphql';
export const createLocalState = () => {
// set an initial value
const localDataVar = makeVar('');
const cacheConfig = {
typePolicies: {
Query: {
fields: {
localData() {
// obtain current value
// triggers when `localDataVar` is updated
return localDataVar();
},
},
},
},
};
// methods that update local state
const localMutations = {
setLocalData(newData) {
localDataVar(newData);
},
clearData() {
localDataVar('');
},
};
return {
cacheConfig,
typeDefs,
localMutations,
};
};
```
Pass the cache config to your Apollo Client:
```javascript
// index.js
// ...
import createDefaultClient from '~/lib/graphql';
import { createLocalState } from './graphql/local_state';
const { cacheConfig, typeDefs, localMutations } = createLocalState();
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { cacheConfig, typeDefs }),
});
return new Vue({
el,
apolloProvider,
provide: {
// inject local state mutations to your app
localMutations,
},
render(h) {
return h(MyApp);
},
});
```
Wherever used, the local query will update as the state updates thanks to the **reactive variable**.
### Using with Vuex
When the Apollo Client is used in Vuex and fetched data is stored in the Vuex store, the Apollo Client cache does not need to be enabled. Otherwise we would have data from the API stored in two places - Vuex store and Apollo Client cache. With Apollo's default settings, a subsequent fetch from the GraphQL API could result in fetching data from Apollo cache (in the case where we have the same query and variables). To prevent this behavior, we need to disable Apollo Client cache by passing a valid `fetchPolicy` option to its constructor:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment