Serverless "to-do" application with AWS AppSync, DynamoDB, and Lambda
Sample "to-do" application to demonstrate the integration of AWS AppSync with AWS DynamoDB via AWS Lambda without VTL. Code is written in TypeScript.
The goal was to build a fully functional application that is very simple with as little boilerplate code and as few libraries as possible.
The project is organized as a monorepo containing two main folders, one for the backend and another for the frontend.
The application is available in the following domains (if not already removed):
Dev: https://todo-dev.markotest.com/
Staging: https://todo-staging.markotest.com/
Production: https://todo.markotest.com/
Backend
Backend is built with Serverless framework. Several plugins are used:
serverless-iam-roles-per-function
- enables individual role per function to improve security,serverless-webpack
- module bundler,serverless-appsync-plugin
- support for AppSync,aws-amplify-serverless-plugin
- exportingschema.json
andaws-exports.js
, that are used by Amplify on frontend,serverless-lift
- deploying frontend as static web site using S3 and CouldFront.
Authentication is done with Amazon Cognito. Username & password login is supported.
Project structure
backend/src/functions
- Lambda functions,backend/src/model
- data model,backend/src/util
- helper functionsbackend/schema.graphql
- GraphQL schema.
Using
- Run
npm run deploy
to deploy the solution
Database: AWS DynamoDB
The single table design is used to structure data - DynamoDB Design Patterns for Single Table Design. The partition key is filled with the user ID, and the sort key with the "Todo" entity ID. For ID, KSUID is used. KSUID is similar to UUID, but it is sortable because the first part contains a timestamp. This solution allows us to retrieve all users' todos by partition key, sorted by date of entering.
Frontend
The frontend is built using React, AWS Amplify, and MaterialUI.
Amplify has two purposes:
- Sign-up and login user.
- Generating TypeScript types from GraphQL.
Using
- Run
npm run generate-gql-types
to generate TypeScript types from GraphQL. You must deploy the backend before because you need generatedschema.json
. - Run
npm run start
to run the app on localhost http://localhost:3000/. You must deploy the backend before because you need generatedaws-exports.js
. - Run
npm run build
to build the app. You must deploy the backend before because you need generatedaws-exports.js
.
CI/CD
CI/CD is created with GitHub actions.
Code: .github/workflows/cicd.yml
Serverless Lift plugin for Serverless framework with its Static website feature is used to deploy frontend.
Custom domain
To have custom domain you should:
- Enter desired domain in serverless.yml
constructs\landing\domain
andcertificate
. - Enter ARN of the certificate in serverless.yml
constructs\landing\certificate
. - After deployment you see:
landing:
url: https://mywebsite.com
cname: s13hocjp.cloudfront.net
You have to create a DNS entry in AWS Route55 that points to your xxx.cloudfront.net
domain. After a few minutes/hours, the domain should be available.