How to use Apollo Client with AppSync?

C.Lee picture C.Lee · Oct 24, 2018 · Viewed 7.1k times · Source

AppSync uses MQTT over WebSockets for its subscription, yet Apollo uses WebSockets. Neither Subscription component or subscribeForMore in Query component works for me when using apollo with AppSync.

One AppSync feature that generated a lot of buzz is its emphasis on real-time data. Under the hood, AppSync’s real-time feature is powered by GraphQL subscriptions. While Apollo bases its subscriptions on WebSockets via subscriptions-transport-ws, subscriptions in GraphQL are actually flexible enough for you to base them on another messaging technology. Instead of WebSockets, AppSync’s subscriptions use MQTT as the transport layer.

Is there any way to make use of AppSync while still using Apollo?

Answer

C.Lee picture C.Lee · Oct 24, 2018

Ok, here is how it worked for me. You'll need to use aws-appsync SDK (https://github.com/awslabs/aws-mobile-appsync-sdk-js) to use Apollo with AppSync. Didn't have to make any other change to make subscription work with AppSync.

Configure ApolloProvider and client:

    // App.js
    import React from 'react';
    import { Platform, StatusBar, StyleSheet, View } from 'react-native';
    import { AppLoading, Asset, Font, Icon } from 'expo';
    import AWSAppSyncClient from 'aws-appsync' // <--------- use this instead of Apollo Client
    import {ApolloProvider} from 'react-apollo' 
    import { Rehydrated } from 'aws-appsync-react' // <--------- Rehydrated is required to work with Apollo

    import config from './aws-exports'
    import { SERVER_ENDPOINT, CHAIN_ID } from 'react-native-dotenv'
    import AppNavigator from './navigation/AppNavigator';

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


    export default class App extends React.Component {
      render() {
        return <ApolloProvider client={client}>
          <Rehydrated>
            <View style={styles.container}>
              <AppNavigator />
            </View>
          </Rehydrated>  
        </ApolloProvider>
    }

Here is how the subscription in a component looks like:

    <Subscription subscription={gql(onCreateBlog)}>
      {({data, loading})=>{
        return <Text>New Item: {JSON.stringify(data)}</Text>
      }}
    </Subscription>