Since we implemented the chat function this time, we will leave an article as a memorandum.
After creating AWS Lambda, I will post an article on front side settings. The AWS side will be created with the configuration of ʻAPI Gateway + Lambda + DynamoDB`.
From API Gateway, press ʻCreate API` and press We will create a WebSocket API.
Set the protocol with the following contents.
Protocol: WebSocket
item | Contents |
---|---|
API name | vue_chat_test |
Route selection formula | $request.body.action |
Description | vue_chat_test |
After creating the API, the screen will change to the screen for creating the root key. This time, we will set each root key below.
Key name | Use |
---|---|
$connect | Used when the client starts WebSocket communication |
$disconnect | Used when the client terminates WebSocket communication |
$default | Used when there is no corresponding root key |
sendmessage | Used when sending a message |
getmessages | Used when getting a message |
However, since you can not create a root key unless you have created a Lambda function, First, create the dynamoDB table and Lambda function.
dynamoDB will be created with the following contents. The configuration is an assumption of a chat where you can see the messages that have arrived to you.
item | Contents | Key setting |
---|---|---|
connection_id | Connection ID | Partition key |
user_id | User ID |
item | Contents | Key setting |
---|---|---|
user_id | Connection ID | Partition key |
created_at | date of creation | Sort key |
message | message |
The runtime is Python3.8
and creates the following Lambda function.
function | Contents | Access authority setting |
---|---|---|
OnConnect | In the connection table Save connection ID / user ID |
dynamoDB |
OnDisconnect | Delete record in connection table | dynamoDB |
SendMessage | Save message | dynamoDB,ExecuteAPI |
GetMessages | Get message | dynamoDB,ExecuteAPI |
import json
import boto3
#Get dynamoDB table
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table('connections')
def lambda_handler(event, context):
#Get "connectionId, userId"
connection_id = event.get('requestContext',{}).get('connectionId')
user_id = event.get('queryStringParameters',{}).get('userId')
#Add to connections table
result = connections.put_item(
Item={
'connection_id': connection_id,
'user_id': str(user_id)
}
)
return { 'statusCode': 200,'body': 'ok' }
import json
import boto3
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table('connections')
def lambda_handler(event, context):
connection_id = event.get('requestContext',{}).get('connectionId')
result = connections.delete_item(Key={ 'connection_id': connection_id })
return { 'statusCode': 200, 'body': 'ok' }
import json
import boto3
import json
from boto3.dynamodb.conditions import Key, Attr
from datetime import datetime, timedelta, timezone
#Get dynamoDB table
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table('connections')
messages = dynamodb.Table('messages')
#TimeZone settings
JST = timezone(timedelta(hours=+9), 'JST')
def lambda_handler(event, context):
#Parameter acquisition
body = json.loads(event["body"])
user_id = body['user_id']
message = body['message']
#Creation date and time
now = "{0:%Y-%m-%d %H:%M:%S}".format(datetime.now(JST))
#Save to message table
messages.put_item(
Item={
'user_id': user_id,
'message': message,
'created_at': now
}
)
#ApiGatewayManagementApi settings
domain_name = event.get('requestContext',{}).get('domainName')
stage = event.get('requestContext',{}).get('stage')
apigw_management = boto3.client('apigatewaymanagementapi',
endpoint_url=F"https://{domain_name}/{stage}")
#Destination user connection_Get id
connection_items = connections.scan(
ProjectionExpression="connection_id",
FilterExpression=Attr("user_id").eq(str(user_id))
).get('Items')
if len(connection_items) == 0:
return { 'statusCode': 200,'body': 'ok' }
#Get message information
get_message_items = messages.query(
KeyConditionExpression=Key("user_id").eq(str(user_id)) & Key("created_at").lte(now),
ScanIndexForward=True
).get('Items')
#Set message if there is a message, empty array if not
content_all = [] if len(get_message_items) == 0 else get_message_items
#Return message to destination user
for item in connection_items:
_ = apigw_management.post_to_connection(ConnectionId=item['connection_id'],
Data=json.dumps(content_all))
return { 'statusCode': 200,'body': 'ok' }
import boto3
import json
from boto3.dynamodb.conditions import Key, Attr
from datetime import datetime, timedelta, timezone
#table definition
dynamodb_client = boto3.client('dynamodb')
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table('connections')
messages = dynamodb.Table('messages')
#TimeZone settings
JST = timezone(timedelta(hours=+9), 'JST')
def lambda_handler(event, context):
#Set parameter information to variable
body = json.loads(event["body"])
user_id = body['user_id']
connection_id = event.get('requestContext',{}).get('connectionId')
domain_name = event.get('requestContext',{}).get('domainName')
stage = event.get('requestContext',{}).get('stage')
#Check if the connection ID matches
connection_items = connections.query(
ProjectionExpression="connection_id",
KeyConditionExpression=Key("connection_id").eq(connection_id),
FilterExpression=Key('user_id').eq(str(user_id)),
).get('Items')
if len(connection_items) == 0:
return { 'statusCode': 500,'body': 'something went wrong' }
#ApiGatewayManagementApi settings
apigw_management = boto3.client('apigatewaymanagementapi',
endpoint_url=F"https://{domain_name}/{stage}")
#Acquisition date and time
now = "{0:%Y-%m-%d %H:%M:%S}".format(datetime.now(JST))
#Get message information
get_message_items = messages.query(
KeyConditionExpression=Key("user_id").eq(str(user_id)) & Key("created_at").lte(now),
ScanIndexForward=True
).get('Items')
#Set message if there is a message, empty array if not
content_all = [] if len(get_message_items) == 0 else get_message_items
#POST a message to the connection
_ = apigw_management.post_to_connection(
ConnectionId=connection_id,
Data=json.dumps(content_all)
)
return {
'statusCode': 200,
'body': 'ok'
}
We will link the created Lambda with the root key of API Gateway.
Root key | Lambda function |
---|---|
$connect | OnConnect |
$disconnect | OnDisconnect |
$default | OnConnect |
sendmessage | SendMessage |
getmessages | GetMessages |
After linking the root key, deploy the WebSocket API.
This time, the stage name is created with Test
.
When the deployment is complete, you will be issued a WebSocket URL
and a connection URL
.
This is the URL required for communication with the front desk.
That's all for the settings on the AWS side, and finally we will only check the operation.
install wscat
$ npm install -g wscat
Use wscat to check the operation and confirm that the data is saved in dynamoDB.
$ wscat -c [WebSocket URL]?userId=A
Connected (press CTRL+C to quit)
> {"action":"sendmessage","user_id": "A", "message": "Test"}
[{"message": "Test", "user_id": "A", "created_at": "2020-08-29 17:22:43"}]
> {"action":"getmessages", "user_id": "A"}
[{"message": "Test", "user_id": "A", "created_at": "2020-08-29 17:22:43"}]
Click here for the status of dynamoDB!
I tried to create AWS settings for chat function with Vue.js + AWS Lambda + dynamo DB
.
This time, I mainly created it to work, so I think that there is not much processing in case of an error, and there are many other things to think about in order to actually implement it.
Next, we will create a front screen using Vue.js and communicate with the API.
If you have any suggestions, please comment!
Recommended Posts