Create your custom Apollo client for AWS AppSync to use Hooks

Guille Acosta
3 min readApr 20, 2020

--

If you are used to work with React and Graphql you know (for sure) Apollo-React. If not, here is its aim:

React Apollo allows you to fetch data from your GraphQL server and use it in building complex and reactive UIs using the React framework. React Apollo may be used in any context that React may be used. In the browser, in React Native, or in Node.js when you want to do server-side rendering.

With its client you are able to request and cache data from any graphql server, but a mayor issue happens when working with AWS (graphql implementation) AppSync.

To be able to connect to AWS AppSync from your React App you need to configure your Apollo React and you’ll also need an extra library called aws-appsync to configure a client for apollo provider as shown here:

import AWSAppSyncClient from 'aws-appsync'
import AppSyncConfig from './aws-exports'
import { ApolloProvider } from 'react-apollo'
import { Rehydrated } from 'aws-appsync-react' // this needs to also be installed when working with React

import App from './App'

const client = new AWSAppSyncClient({
url: AppSyncConfig.graphqlEndpoint,
region: AppSyncConfig.region,
auth: {
type: AppSyncConfig.authenticationType,
apiKey: AppSyncConfig.apiKey,
// jwtToken: async () => token, // Required when you use Cognito UserPools OR OpenID Connect. token object is obtained previously
}
})

const WithProvider = () => (
<ApolloProvider client={client}>
<Rehydrated>
<App />
</Rehydrated>
</ApolloProvider>
)

export default WithProvider

This is working just fine for apollo-client version 2.5, but it’s not working to get advantage from useQuery, useMutation and other hooks available on version 2.6. The problem is AWSAppSyncClient from aws-appsync has a fixed dependency to:

“apollo-client”: “2.4.6”

An alternative would be using something like npx-force-resolution to set all dependencies for apollo-client to 2.6, but this is not as clean as expected. Other option could be fork aws-appsync and fix dependencies.

Best option so far (until aws-appsync gets updated) it’s to create your own client instead of aws-appsync one.

import { ApolloProvider } from '@apollo/react-hooks';
import { ApolloLink } from 'apollo-link';
import { createAuthLink } from 'aws-appsync-auth-link';
import { createHttpLink } from 'apollo-link-http';
import { AppSyncConfig } from '.aws-exports';
import ApolloClient from 'apollo-client';
const url = AppSyncConfig.graphqlEndpoint;
const region = AppSyncConfig.region;
const auth = {
type: AppSyncConfig.authenticationType,
apiKey: AppSyncConfig.apiKey
};
const link = ApolloLink.from([
createAuthLink({ url, region, auth }),
createHttpLink({ uri: url })
]);
const client = new ApolloClient({
link,
cache: new InMemoryCache()
});

const WithProvider = () => (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
)

export default WithProvider

With this you’re able to use useQuery and useMutation in your React Components just like Apollo docs suggest:

import gql from 'graphql-tag';
import { useQuery } from '@apollo/react-hooks';
const GET_DOG_PHOTO = gql`
query Dog($breed: String!) {
dog(breed: $breed) {
id
displayImage
}
}
`;

function DogPhoto({ breed }) {
const { loading, error, data } = useQuery(GET_DOG_PHOTO, {
variables: { breed },
});

if (loading) return null;
if (error) return `Error! ${error}`;

return (
<img src={data.dog.displayImage} style={{ height: 100, width: 100 }} />
);
}

Hope this help you. Happy Coding!

--

--