This CDK project is a sample solution for achievement microservices in games.
The sample solution contains AWS Lambda Functions, Amazon DynamoDB Tables, Amazon SQS Queues and Amazon API Gateway.
- the solution is constructed with only serverless services
- the solution handles achievement progress additions asynchronously
- a single progress can trigger multiple achievements
- for example, progress with winning matches could trigger achievements for 10 wins, 50 wins and 100 wins.
- achievement requirements can be appended, and new achievements will be unlocked on the next progress event, as long as the new requirements are after the previous requirements,
- for example, if there are 10 wins and 50 wins achievements, then you can add 100 wins but not 30 wins.
- the solution has an SQS queue in front, so multiple backend services can send progress events
- the solution has an SQS queue for outputting achieved events, you can add handlers to send achieved events back to clients
- for example, have an API server with websocket connection and poll events from the queue
- the solution is decoupled from game specific details (achievement descriptions, images, titles, and more), the solution simply handles progresses and achievements with IDs
- the solution handles duplicated messages gracefully using DynamoDB conditional Put
- another service, such as an application server, has bidirectional connection with clients
- achievement metadata is stored separately with all IDs matched
As Shown in the diagram below, there are three Lambda functions, two SQS queues in front of DynamoDB.
In Queue
handles all input messages from game backend services, and Out Handler
can be replaced or used to talk back to game clients.
There also is an API Gateway for admin purposes, however another API Gateway may be required for requesting current player achievements.
Each entry represents an achieved achievement by a player with player ID
PK: player_id | SK: id | achieved_at |
---|---|---|
string: player ID | string achievement ID | timestamp |
Each entry represents current progress for specific progress with progress ID by a player with player ID
PK: player_id | SK: id | progress | last_updated |
---|---|---|---|
string: player ID | string: progress ID | number: current progress | timestamp |
Each entry represents an achievement and its requirement, a requirement has progress ID and required amount of progress
PK: achievement_id | GSI PK: required_progress | GSI SK: required_amount |
---|---|---|
string: achievement ID | string: progress ID | number: required amount |
Each entry represents a message from In Queue, a message only stays in this table for 5 minutes, this is used for duplication check
PK: message_id | TTL: ttl |
---|---|
string: sqs message ID | number: ttl timestamp |
{
“player_id”: string,
“progress_id”: string,
“progress_increment”: number,
}
{
“player_id”: string,
“achievement_id”: string,
}
- An AWS account
- Nodejs LTS installed, such as 14.x
- Install Docker Engine
To deploy the example stack to your default AWS account/region, under project root folder, run:
yarn install
to install all the dependenciescdk deploy
to deploy this stack to your default AWS account/region
Once the deployment is completed, you should be able to locate API Gateway url in Outputs
tab. Use the url and send POST
request to insert achievement data. Sample request body is:\
{
"achievement_id": "a1",
"required_progress": "p1",
"required_amount": 3,
}
With curl
:\
$ curl -XPOST https://<YOUR ENDPOINT>/prod/achievements \
-H "Content-Type: application/json" \
-d '{"achievement_id": "a1", "required_progress": "p1", "required_amount": 3}'
To test your service, you can start sending messages to In Queue
. You can use test message located in test/testMessage.json
.
To send messages, you can either:
- use AWS Console, go to Amazon SQS, find a queue with
InQueue
in its name, then go toSend and receive messages
- use AWS CLI, for example
aws sqs send-message --queue-url <YOUR QUEUE URL> --message-body file://test/testMessage.json
This solution is licensed under the MIT-0 License. See the LICENSE file.
Also, this application uses below open source project,