banner 728x90

Building a server-free real-time chat application with AWS AppSync

banner 728x90

Today most digital media use comes from mobile devices. People communicate with their apps via multiple devices, via different connections (3G, LTE, Wi-Fi, etc.) and also offline. It is important to provide a consistent user experience for different connection types. At the same time there is an increase in the number of apps and apps for social media with social elements to enable activities such as collaboration, message exchange and comments. These activities require a real-time opportunity to automatically present updated information to users.

AWS AppSync, introduced at re: Invent 2017, is a fully managed GraphQL service. It makes it easy to build collaborative mobile and web applications that provide responsive user experiences and offer offline and real-time capabilities. You can find more information about GraphQL in the AWS AppSync Developer Guide

Today we introduce ChatQL, a new launch application for an Angular Progressive Web App (PWA). It is built with AWS AppSync and shows you how to create a real-time chat application. In this blog post we present an overview of the application and dive into AWS AppSync and the front-end implementation.

building a server free real time chat application with aws appsync - Building a server-free real-time chat application with AWS AppSync

Implement the application

You can clone, install, test, build and deploy ChatQL by following the instructions on the GitHub repository. You can configure and deploy the user logon, analysis and hosting backend and related AWS services automatically using a few AWS Mobile Command Line Interface (CLI) commands.

Architecture overview

1520365645 306 building a server free real time chat application with aws appsync - Building a server-free real-time chat application with AWS AppSync

The application uses AWS AppSync to interact with the backend data sources and uses the AWS AppSync SDK for JavaScript. The AWS AppSync API is defined by a GraphQL schema in which types and operations (query & # 39; s or mutations) are linked to resolvers. These resolvers use application and response mapping templates to read and write data from specific data sources. The application uses four Amazon Dynamo DB tables:
  • User table – saves usernames and internal identifiers
  • Message table – messages that correlate users, conversations, and timings
  • Conversation table – conversations about call names and internal IDs
  • User Conversion Table – linking users to conversations

The following graph is a high-level representation of our data model. It is composed of nodes and edges. Cardinality information for each connected set of nodes is displayed along the edges. The nodes represent the data that we store and the edges represent associations between the data. The graph view helps us understand how the data relate to itself and how it should be stored. Note that we store the data in DynamoDB. For a GraphQL application, it is not necessary to use a graph database.

1520365645 964 building a server free real time chat application with aws appsync - Building a server-free real-time chat application with AWS AppSync

Users can see a list of all the other users and can start conversations with one of them. However, they can only see conversations they have initiated or for which they have been invited. To make it all work, we benefit from specific GraphQL operations:

  • Query & # 39; s – Get the list of users, related conversations and messages
  • Mutations – create users, messages, conversations and relations between users and conversations
  • Subscriptions – automatically retrieve new messages in a conversation as soon as they are received in the back-end

The chat application consists of a function module "chat app" that is composed of various components. Each component works together with the simple Angular service of the module that provides access to the AWS AppSync client.

1520365646 287 building a server free real time chat application with aws appsync - Building a server-free real-time chat application with AWS AppSync


Users must authenticate to use ChatQL. With AWS AppSync you can protect and secure your data with API keys, AWS IAM or Amazon Cognito user pools. The ChatQL application uses Amazon Cognito user pools and allows users to register their account and log in. After successful authentication, Amazon Cognito returns a JWT token to the application used to identify the user and grant access to the AWS AppSync GraphQL API.

ChatQL uses the AWS Amplify library to easily implement authentication. AWS Amplify is a declarative library that makes it easy to implement general tasks (such as authentication) in front-end and mobile applications. A thin standalone function module implements the onboarding page & # 39; s for the app – calls Amplify Auth for signing in, logging in, confirming password and logging out. You make this module available in the application by adding it to imports in app.module.ts .

  import  from & # 39; ./ auth / auth.module & # 39 ;;
import: [

Interaction with data

Retrieve and receive messages

You retrieve messages with the function loadMessages in chat-message-view.component.ts by calling the AWS AppSync client watchQuery with the allMessageConnection search:

  query getConversationMessages ($ conversationId: ID!, $ After: String, $ first: Int)   

The query returns a MessageConnection -type, which is a GraphQL connection. A connection is a term that describes paginated data. This allows us to efficiently search for a part of the messages. A connection usually consists of a series of data (the paginated field) and a token / cursor that points to where the next query should begin.

  type MessageConnection   

In the allMessageConnection query, we pass a mandatory conversationId argument. We can also pass a token to the optional after argument that indicates from which item we must start searching for data. Optionally, we can also specify how many items to retrieve with the first argument . The following is the answer template for the query:

"version": "2017-02-28",
"Operation": "Search",
"search": ,
"scanIndexForward": false,
"limit": #if ($ ) $  #else 20 #end,
"nextToken": #if ($ ) "$ " #else null #end

We use a "cache-and-network" retrieval policy in watchQuery to retrieve the messages. In this way, requests are made simultaneously to the client cache and to the back end for messages. This allows a quick response to the user if there is already a list of messages in the cache. The cache is then updated by new messages that are returned by the network. We subscribe to the observable object that watchQuery returns to update our message list and save the returned nextToken .

Retrieving and paging more messages

When an existing conversation is opened, the application loads only the last 10 messages. A call can contain any amount of messages. We do not want to recall them all at once, because this would affect the application's responsiveness. The application uses the allMessageConnection query with the first argument to manage how messages are retrieved in batches. The nextToken stored from the previous query execution is used to indicate where to retrieve the message.

  const result = this.observedQuery.fetchMore ();  

Additional messages are loaded by scrolling up in the message view. The scroll action triggers an event that calls loadMoreMessages in chat-message-view.component.ts . We call fetchMore about the original observable object with nextToken and add the new set of returned messages to our existing list. This enables a seamless infinite scrolling experience for the end user.

Subscribe to and deal with new messages

During a conversation the application pushes new messages in real time to the chat. AWS AppSync offers this functionality with subscriptions. We subscribe to new messages in the current call and a subscription is called when a message is created. To do this, we call the function subscribeToMore for the observable object that is returned by the function [QueryQuery

  this.subscription = observeable.subscribeToMore ();  

We pass the ID of the current call to the subscription and add newly received messages to the front of our existing message list when a message is pushed to our chat app.

Sending a message and optimistic comments

To update our backend with GraphQL, we use mutations. The app uses a createMessage -mutation to add a message to a conversation. However, GraphQL operations are not possible when the backend can not be reached. This limits the effectiveness of a typical app.

The AWS AppSync SDK for JavaScript offers offline capabilities with support for optimistic user interfaces. These features in our PWA app allow users to communicate with the app even when it is offline or experiencing network connectivity issues. With our app users can send messages at any time - even if they are offline. When a user sends a message, it is immediately displayed in the message view, without waiting for a server response. The corresponding mutation is also saved. If the mutation can not be executed, it will be sent to the backend when the app comes back online.

To send a message, we first build a message object. We define the ID of the message on the customer's side. We do this so that we can properly reverse the optimistic data when the backend reply with the same ID is received. Because we retrieve our messages in reverse chronological order (oldest to newest) on the backend, we use the current date as part of our ID (which is used as a key in our DynamoDB table). We add UUIDv4 to the ID to ensure uniqueness.

  const date = ();
const message: message = ;  

Our mutation defines which fields are returned when the mutation is successfully executed.

  mutation createMessage ($ id: ID!, $ Content: String, $ conversationId: ID!, $ CreatedAt: String!)   

To take advantage of the offline opportunity, we offer an optimistic response in our mutation that shows how the server response should look like. In our case, this is just a reply object with the message.

  client.mutate ();  

The app provides visual guidance to let the user know if a message is still to be sent or if the message has been received by the backend. The message object sent in the transaction has a isSent flag set to false. The flag determines the color of a check mark that appears for each message.

When our transaction is handled on the backend, a matching message object is returned with the flag set to true. This value change automatically changes the check mark color from gray to green.

1520365647 475 building a server free real time chat application with aws appsync - Building a server-free real-time chat application with AWS AppSync

Analysis of collections

ChatQL collects user session statistics. It also tracks the number of calls made and messages sent in Amazon Pinpoint. You can do this by using AWS Amplify, which is also used to implement authentication. We configure AWS Amplify once in app.module.ts and call Analytics.record when a message is sent after a call is made.


  import Amplify from & # 39; aws-amplify & # 39 ;;
import aws_exports from & # 39; ../ aws-exports & # 39 ;;

Amplify.configure (aws_exports)  


  import  from & # 39; aws-amplify & # 39 ;;
Analytics.record (& # 39; Chat MSG Sent & # 39;);  

You can see the aggregated statistics in the Amazon Pinpoint console.

1520365647 128 building a server free real time chat application with aws appsync - Building a server-free real-time chat application with AWS AppSync


In this blog post we discussed the new ChatQL Angular PWA launch application built with AWS AppSync and the AWS AppSync SDK for JavaScript. AWS AppSync makes it easy for our app to communicate with backend data sources and to implement real-time and offline capabilities.

We have described how our app communicates with messages (querying, retrieving, creating, subscribing) and how we have used optimistic responses to offer the user a seamless, enhanced experience. There are also other parts of the app that communicate with other parts of our backend data sources with AWS AppSync. We encourage you to also dive in by getting started with the code, documentation and AWS resources configured and implemented in the backend.

We hope this starter app will help you get started with AWS AppSync. You can find the code and information about publishing the app in the GitHub repro.

This post was contributed by Ed Lima and Brice Pelle. Ed is a Solutions Architect who is passionate about Serverless, Mobile, IoT as well as good architect AWS customers helps travel in the cloud. Brice is an Enterprise Support Lead and mobile support specialist. Brice also likes app development in his spare time.

banner 728x90
    Build a user settings store with AWS AppSync
    Build a user settings store with AWS AppSync
    Amazon Cognito Sync is a service that
    Synchronize user settings for Android with AWS AppSync
    Synchronize user settings for Android with AWS AppSync
    Amazon Cognito Sync is a service that
    Script & Style Show: Episode 10: Dojo
    Script & Style Show: Episode 10: Dojo
    In this episode welcome David and Todd

    Leave a reply "Building a server-free real-time chat application with AWS AppSync"

    Must read×