HOME
CAREER OPPORTUNITIES
COMMUNITY
Back to Blog

Creating a real time chat app with AWS Appsync, DynamoDB and Cognito

Published At: February 25th, 2020

Project 2: Real time chat service (AWS Appsync)

Today we decided to explore a relatively new AWS service called AppSync as we are trying to build a social media app ourselves that will leverage AWS ( we are build a classic chat app ). AWS AppSync is a new service that enables developers to manage and synchronize mobile app data in real time across devices and users, but still allows the data to be accessed and altered when the mobile device is in an offline state.

AWS AppSync is a new service that enables developers to manage and synchronize mobile app data in real time across devices and users, but still allows the data to be accessed and altered when the mobile device is in an offline state.

Step 1:

Installed the dependencies, only 2.2 mbs total ( no bundle hysteria here ).

Bundles

$ npm install -g @aws-amplify/cli $ amplify configure $ amplify init

AmplifyInit

Of course we are using Amplify from AWS, it’s a great tool unless you want to go hardcore and write the scripts directly in CloudFormation, later we can discuss that or using SAM which would provide you more control and flexibility over the services you create/maintain. During the set up process we select to use Cognito for user auth:

AmplifyAddAPI

Created the project in us-west-2 arn:aws:amplify:us-west-2:**apps/

Step 2: Install the api to use appsync, etc:

$ amplify add api

We are using GraphQL !!

Define a GraphQL object type and annotate it with the @model directive to store objects of that type in DynamoDB and automatically configure CRUDL queries and mutations.

type Post @model { id: ID! # id: ID! is a required attribute. title: String! tags: [String!]! }

For our case we defined this in our schema.js file in the project as such:

type Room @model { id: ID! createdAt: String updatedAt: String messages: [Message] @connection(name: "RoomMessages", keyField: "roomId", sortField: "when") } type Message @model(subscriptions: null) { id: ID! content: String! when: String! roomId: ID owner: String room: Room @connection(name: "RoomMessages", keyField: "roomId") } type Subscription { onCreateMessage(roomId: ID!): Message @aws_subscribe(mutations: ["createMessage"]) }

Now we let amplify do the magic ( uses cloudformation to create assets such as dynamodb tables based on previously mentioned schema file)

$ amplify push

Selecting the options to create graphql api in javasacript file name pattern for graphql queries: src\graphql***.js

ChatDynamodb

Note that in order to do this you must have the right policy definition in IAM for the account you are using

In a few more minutes you will have your endpoint up and running! GraphQL endpoint: https://ni4vxhw3gvfetdnrela7af2szy.appsync-api.us-west-2.amazonaws.com/graphql

Step 3: Front end followed steps from existing blog post to create a chat app in React, connected to Apollo, Cognitofor logging on and/or creating a new account:

CognitoLogin ChatAppUserPool

This means we are effectively using our back end code generated with AWS amplify scripts which were saved automatically to our aws.exports file in our react project (includes graphql endpoint we created for the chat app).

This is how my backend looks at this point from AWS console ( Appsync )

AppSyncSchema

If you want to query data directly in AWS Appsync you can do so in the Queries option and enter a JSON structure such as this:

query { listRooms { items { id createdAt } } }

While building the front end using React JS we found of course issues not stated in the original blog but the main problem was that aws appsync does not jive well with the latest version of react apollo, hydrated.js is not found literally for offline functionality so revert to react apollo version 2.5.8 which allows hydrated to work. Finally chat is working, chat data is served back to the client via graphql apollo from appsync:

RealTimeChatCodeSandBox

Note I used codesandbox which is a nice tool to test/debug your app in real time. It seems that AWS has linked up with Apollo to provide a slick graphql API via Appsync which provides the following benefits:

  1. Reduce number of requests back and forth ( less data consumption )
  2. Optionality to have offline functionality thanks to built in redux + apollo
  3. The benefit of being an AWS service that can leverage other services, i.e. Cognito, Dynamodb, etc.

Give it a try:

Github Link

I still owe you our next blog series on Comparing AWS and GCP: File Uploading Service. We want to see which is more performant and cheaper again in a serverless environment ( Cloud Function -> DataStore, API Gateway / Lambda -> S3)

All the best!