Serverless approach to build backend WebSocket Chat API

In traditional HTTP model of web, a client initiates request and a server’s job is to respond to that request. Later, a number of different strategies came to allow the server to push data to the client. One of the most popular strategies was long polling. This involves keeping an HTTP connection open until the server has data to send to the client. But this strategy came with a problem that is latency. Multiple requests were sent to the server with a bunch of unnecessary cookies and headers data. For example, if you are building a browser based gaming application then it should have very low latency to run smoothly. So we need a persistent and a low latency connection to fulfill client and server communication. This is exactly what WebSocket provides.

How WebSocket works

WebSocket provides a persistent connection between the client and server assisting both of them to send files simultaneously. The client establishes a WebSocket connection with HTTP GET request by handshaking process of WebSocket. The request carries an Upgrade header to the server requesting to initiate a WebSocket connection. An important thing to notice that the WebSocket URL uses WS. Similarly, we have WSS for secure socket connection like HTTPS.

In this blog, I am going to show how will you use WebSocket to setup a Serverless backend API for a real-time chat application and deploy it on AWS.

What do you need for this setup?

An AWS account and an IAM user with Admin access.

Follow the below steps

Step 1: Create IAM Roles

To know how to create an IAM role and attach policies, refer to this documentation.

You need to create two IAM roles.

  • Create an IAM role for API Gateway and add following permission: lambda:InvokeFunction
  • Create an IAM role for Lambda Functions and add following permissions: dynamodb:PutItem, dynamodb:DeleteItem, dynamodb:Scan, execute-api:*, logs:CreateLogGroup, logs:CreateLogStream, logs:PutLogEvents.

Step 2: Create a WebSocket API in API Gateway

  • In the API Gateway console, choose Create API and then New API.
  • Under Choose the Protocol, choose WebSocket.
  • Enter a name(For now enter My Chat API) for API name.
  • enter $request.body.action for Route Selection Expression.
  • Click on Create API.

Step 3: Create Lambda Functions

We will create two Lambda functions. Use previously created role for Lambda for all functions.

  • Create first Lambda function and for name, enter connection. After creation, copy this code into Lambda index.js and then save it. In this Lambda, we are storing newly connected connection ID in Dynamo DB.
  • Create second Lambda function and for name, enter sendMessage. After creation, copy this code into Lambda index.js and then save it. Note: This Lambda needs some dependencies. So you need to upload aws-sdk in this Lambda function. In this lambda function, we are deleting connection ID when the connection is closed or disconnected.

Step 4: Manage Routes

When you create a Websocket API in API Gateway, it comes with predefined routes($connect, $disconnect and $default). Additionally, we will create a custom route which will be responsible for handling messages between client and server.

To create custom route follow these steps:

  • In the API Gateway console, under My Chat API, choose Routes.
  • For New Route Key, enter sendmessage and confirm it.

You have created custom route. Now a Lambda integration is required for this route. Integrate sendMessage lambda with this route and use API Gateway IAM role in this integration. To know how to integrate lambda, refer this documentation. Also integrate connection lambda function with all predefined routes.

Step 5: Deploy the WebSocket API

You are deploying for the first time, so create a stage and for name enter dev. To know how to deploy follow this documentation.

Now test the Chat API

To test the API, we will use wscat, an open source CLI. To know how to use wscat, follow this documentation.

Follow the steps to test:

$ wscat -c wss://{YOUR-API-ID}.execute-api.{YOUR-REGION}.amazonaws.com/dev
connected (press CTRL+C to quit)
> {"action":"sendmessage", "data":"hello world"}
< hello world

Now you will see that we are able to send messages to the server and then getting sent message as a response. If any third person connects and sends message in same socket by using the WebSocket API then you can see that message also.

Conclusion

Now we know how to use WebSocket API in API Gateway, exchanging messages between client and server. We have used CLI to test it out. But you can build a nice frontend and integrate with this backend application.