Search code examples
websocketmqttapolloreact-apolloaws-appsync

How to use Apollo Client with AppSync?


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?


Solution

  • 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>