Integrate apollo client in react-native app #1

Hyo
dooboolab
Published in
4 min readJan 27, 2020

This story is about integrating apollo client in order to use graphql APIs in react native application.

Firstly, you need to install the necessary packages from Apollo and graphql.

yarn add @apollo/react-hooks apollo-boost apollo-link apollo-link-context apollo-link-error apollo-link-ws apollo-utilities graphql

Below versions are what’s currently installed.

"@apollo/react-hooks": "^3.1.3",
"apollo-boost": "^0.4.7",
"apollo-link": "^1.2.13",
"apollo-link-context": "^1.0.19",
"apollo-link-error": "^1.1.12",
"apollo-link-ws": "^1.0.19",
"apollo-utilities": "^1.3.3",
"graphql": "^14.5.8",

Sometimes you’d like to use resolution in package.json to use same graphql version inside your project. If other packages you’ve installed use other graphql version, it might result in bugs for some other side effects.

"resolutions": {
"graphql": "14.5.8"
}

To use @apollo/react-hooks inside your components, you need to wrap your parent component with ApolloProvider. Previously, this design was implemented from react-apollo-hooks package by @trojanowski but today, Apollo has implemented its official one.

<ApolloProvider client={client}>
<App />
</ApolloProvider>

The key in the above code is about the client we are passing into ApolloProvider. We’ll now discuss on this variable.

In ApolloProvider, we need to pass the class variable, ApolloClient which looks like client = new ApolloClient.

Since, Apollo provides vast options to initialize the ApolloClient, what we want to do is to separate a file Client.ts.

  1. Create http link that connects to the endpoint of our graphql apis.
const httpLink = new HttpLink({
uri: `${GRAPHQL_URL}`,
});

2. Create web socket link which is used for subscription.

const wsLink = new WebSocketLink({
uri: `ws://${GRAPHQL_URL}`,
options: { reconnect: true },
});

3. Since we’d like to gain more performance using InMemoryCache provided by Apollo, let’s create it. It’s also useful to cache the same results given by query and mutation queries with fragments.

const cache = new InMemoryCache();

4. This step is pretty useful since most applications need it. Since most of them like to handle the auth flow, Apollo also has provided a way to set middleware using the concept of context. This part is where it might be different in React. In React, you might want to use browser cache instead of AsyncStorage. After creating authLink, we concat this into one link.

const authLink = setContext(async (_, { headers }) => {
const token = await AsyncStorage.getItem('token');
return {
headers: {
...headers,
Authorization: token,
},
};
});
const httpAuthLink = authLink.concat(httpLink);

5. (Optional) Other steps that had been already introduced might be optional too. However, I thought they are pretty essential. Here, we’d like to add an errorLink which provides useful error logs when unexpected results are returned from the endpoint. This utility is provided in separate package, apollo-link-error.

const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
// eslint-disable-next-line no-console
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
}
// eslint-disable-next-line no-console
if (networkError) console.log(`[Network error]: ${networkError}`);
});

6. To distinguish the subscription and other graphql queries, we need to use the split function provided by apollo-link. Then we’ve provided web socket link and http link with auth provided in step 4. Bear in mind that you should provide http link at the very bottom since there are several issues related to this.

const link = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpAuthLink,
);

7. Finally, let’s create ApolloClient and export it with all the setups.

export default new ApolloClient({
link: ApolloLink.from([
errorLink,
link,
]),
cache,
});

It might be confusing for someone to integrate the Apollo client to his or her application. It is because it provides several ways to integrate it and their packages are very fragmented (double-edged swords). However, you should not worry because you don’t always have to understand everything before you can use it. There are already some other good practices to integrate them.

To summarize what I’ve provided here is listed below.

  1. Integrate apollo client to use graphql apis for queries and mutations.
  2. Add ability for auth flow in order to request graphql queries with headers when users have already signed in.
  3. Integrate web socket to use subscription query.
  4. Use in-memory caching.
  5. Add errorLink for debugging.

If you understand what code is doing, you can just copy and paste it and use it. You can also share practices to us so we can upgrade our Client.ts.

Above is a gist. Please don’t forget to star it if you think it is helpful 😃

Thanks for reading. Happy Graphql!

--

--