Looking for Senior AWS Serverless Architects & Engineers?
Let's TalkAmazon Web Services’ (AWS) AppSync is a great way to implement GraphQL in your applications. GraphQL gives you the power to specify what fields you want in an API call, enforce a schema for a NoSQL database, and more.
An equally important feature that never gets much love is the GraphQL subscription. Subscriptions bring your site to life by watching for specific data changes and updating local information whenever those events take place.
Think Facebook: when your friend likes your status you can see that change almost instantly. Multi-user applications like chat rooms need this functionality to work so thankfully AppSync provides an easy, out of the box way for you to set this up in minutes.
As a quick note this tutorial assumes a working knowledge of AppSync and is best for adapting an existing app. If you don’t already have an AppSync app or would just like to learn more please read our deep dive into GraphQL and our tutorial on deploying AppSync apps.
For starters let’s look at an AppSync query without a subscription. Here I have a dashboard that shows the user all their event invitations. My starting React component looks like this:
import React, { Component } from 'react';
import { compose, graphql } from 'react-apollo';
import GetUserQuery from './GetUser';
class Dashboard extends Component {
render() {
return (
{/*YOUR APP*/}
)
}
}
export default compose(
graphql(GetUserQuery, {
name: "GetUserQuery",
options: props => ({
fetchPolicy: 'cache-and-network',
variables: {
id: props.userId
}
}),
props: (props) => {
return {
getUser: props.GetUserQuery.getUser,
loading: props.GetUserQuery.loading,
error: props.GetUserQuery.error
};
}
})
)(Dashboard);
This technically works but what happens if another user invites me while I have my dashboard open?
Nothing that I can see! The page must be refreshed before it shows up. If your site handles real-time changes this delay is more than just annoying, it’s app-breaking.
You can get around this by simply including a subscription:
import React, { Component } from 'react';
import OnUpdateUser from './OnUpdateUser';
...
class Dashboard extends Component {
componentDidUpdate(){
if(this.props.subscribeToNewEvents){
this.props.subscribeToNewEvents();
}
}
...
}
export default compose(
graphql(GetUserQuery, {
name: "GetUserQuery",
options: props => ({
fetchPolicy: 'cache-and-network',
variables: {
id: props.userId
}
}),
props: (props) => {
return {
getUser: props.GetUserQuery.getUser,
loading: props.GetUserQuery.loading,
error: props.GetUserQuery.error,
subscribeToNewEvents: params => {
props.GetUserQuery.subscribeToMore({
document: OnUpdateUser,
variables: {
id: props.ownProps.userId
},
updateQuery: (prev, { subscriptionData: { data : { onUpdateUser } } }) => {
return {
getUser: onUpdateUser
};
}
});
}
};
}
})
)(Dashboard);
Here we added the subscribeToNewEvents function to GetUserQuery’s props and then called it in in the app within componentDidUpdate(). This takes advantage of AppSync’s built-in web socket to constantly listen for the GraphQL function described in your schema.
Put differently we’re telling our app to keep an eye on incoming AppSync requests and update the display if anything changes. Here you can see it in action:
Not bad for a few lines of code!
It’s worth noting that subscriptions only catch changes made through GraphQL so if you directly edit underlying data it won’t trigger an update. Make sure to go full AppSync if you want to keep things live!
More detailed snippets of code can be found here. These are primarily for reference while updating an existing query — again if you don’t have your own example just follow this tutorial first.
And… that’s it! Just a few lines to set your AppSync app with live updates. Hope you found this helpful and let me know if you have any questions or comments below.