loading...

Migrate react-apollo from v2 to v3 in conjunction with AWS AppSync

danielbayerlein profile image Daniel Bayerlein Updated on ・2 min read

The implementation between Apollo and AWS AppSync is very good, but some time ago version 3 of react-apollo was released. Unfortunately this version is no longer compatible with the aws-appsync package.

The latest version of react-apollo provides new React Hooks and introduces a new monorepo structure.

You'll find an issue on GitHub that describes the incompatibility:

React-apollo 3.0 with aws-appsync-react #448

Xocix avatar
Xocix posted on

Do you want to request a feature or report a bug? Bug

What is the current behavior? Installing react-apollo 3.0 makes the Rehydrated component stop working. Going back to react-apollo 2.5.8 makes it work again

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Error message recieved: The context client is marked as required in Rehydrated, but its value is undefined.

What is the expected behavior? Rehydrated should have a client to be able to rehydrate

I didn't follow up on it anymore, because I thought there would be an update to fix the problem soon. But that's not what happened 🙃. The issue now contains 51 comments. Between all the comments with the question about "the current status" is hidden the solution.

Implementation with react-apollo version 2.x

In this example I use the aws-appsync, aws-appsync-react and react-apollo package. Your implementation should probably look like the following:

import React from 'react'
import ReactDOM from 'react-dom'
import Auth from '@aws-amplify/auth'
import AWSAppSyncClient from 'aws-appsync'
import { ApolloProvider } from 'react-apollo'
import { Rehydrated } from 'aws-appsync-react'

import App from './containers/App'
import AppSyncConfig from './aws-exports'

const appSyncConfig = {
  url: AppSyncConfig.graphqlEndpoint,
  region: AppSyncConfig.region,
  auth: {
    type: AppSyncConfig.authenticationType,
    jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken()
  },
  disableOffline: true
}

const appSyncOptions = {
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'cache-and-network'
    }
  }
}

const client = new AWSAppSyncClient(appSyncConfig, appSyncOptions)

ReactDOM.render(
  <ApolloProvider client={client}>
    <Rehydrated>
      <App />
    </Rehydrated>
  </ApolloProvider>,
  document.getElementById('app')
)

Implementation with react-apollo version 3.x:

⚠️ This solution does not include offline support. ⚠️

With the latest version of react-apollo (3.x), the implementation also changes. For the new implementation you need the aws-appsync-auth-link, aws-appsync-subscription-link, apollo-link, apollo-client, apollo-cache-inmemory and @apollo/react-common package.

import React from 'react'
import ReactDOM from 'react-dom'
import { createAuthLink } from 'aws-appsync-auth-link'
import { createSubscriptionHandshakeLink } from 'aws-appsync-subscription-link'
import { ApolloProvider } from '@apollo/react-common'
import { ApolloLink } from 'apollo-link'
import ApolloClient from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import Auth from '@aws-amplify/auth'

import App from './containers/App'
import AppSyncConfig from './aws-exports'

const config = {
  url: AppSyncConfig.graphqlEndpoint,
  region: AppSyncConfig.region,
  auth: {
    type: AppSyncConfig.authenticationType,
    jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken()
  }
}

const client = new ApolloClient({
  link: ApolloLink.from([
    createAuthLink(config),
    createSubscriptionHandshakeLink(config)
  ]),
  cache: new InMemoryCache(),
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'cache-and-network'
    }
  }
})

ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
  document.getElementById('app')
)

Ready for react-apollo 3.x

Now you can use the latest features of Apollo. 🦦

Posted on by:

danielbayerlein profile

Daniel Bayerlein

@danielbayerlein

👨‍💻 Architect & Web Dev ❤️ JavaScript, React and GraphQL 😍 Full Stack Serverless

Discussion

markdown guide