Familiary with DynamoDB. This post will not be an overview of DynamoDB development.
Getting started
We will clone the working repo from the previous blog post as a starting point:
$ git clone https://github.com/okeeffed/using-the-aws-cdk-with-localstack-and-aws-cdk-local dynamodb-with-localstack-and-the-aws-cdk
$ cd building-a-cdn-with-s3-cloudfront-and-the-aws-cdk
$ npm i
# if install fails, remove the lockfile and try again
At this stage, we will have the app in a basic working state.
In order to create the CDN stack, we will require the following AWS CDK libraries:
@aws-cdk/core
@aws-cdk/aws-dynamodb
We can install these prior to doing any work:
npm i @aws-cdk/core @aws-cdk/aws-dynamodb
The repository that we cloned already has a upgrade script supplied. We can use this to ensure our CDK packages are at parity:
npm run upgrade
We are now at a stage to write our construct.
Writing a single-table construct
In our particular case, I am aiming to write a re-useable construct that has single-table schema design at the forefront as well as being inclusive of two secondary indexes GSI1 and GSI2.
Let's create a folder lib/construct-single-table-dynamo and add a barrel file and a file for the construct:
As much as possible, we want to invert control to the consumer of the construct while also locking in some best practices around single-table design.
As a starter, let's prepare our lib/construct-single-table-dynamo/construct-single-table-dynamo.ts with the following code:
import * as cdk from "@aws-cdk/core";
import * as dynamodb from "@aws-cdk/aws-dynamodb";
type SingleTableGlobalSecondaryIndex = Omit<
dynamodb.GlobalSecondaryIndexProps,
"indexName" | "partitionKey" | "sortKey"
>;
export interface ConstructSingleTableDynamoProps extends cdk.StackProps {
tableProps: Omit<dynamodb.TableProps, "partitionKey" | "sortKey">;
GSI1Props?: SingleTableGlobalSecondaryIndex;
GSI2Props?: SingleTableGlobalSecondaryIndex;
}
export class ConstructSingleTableDynamo extends cdk.Construct {
constructor(
scope: cdk.Construct,
id: string,
props?: ConstructSingleTableDynamoProps
) {
super(scope, id);
// ... ready to add our code
}
}
This code will enable our construct to take three props:
tableProps to extend our table without allow the user to alter the partitionKey or sortKey.
Optional GSI1Props to extend the first global secondary index without being able to alter the indexName, partitionKey or sortKey.
Optional GSI2Props to extend the second global secondary index without being able to alter the indexName, partitionKey or sortKey.
We will provide sensible defaults here. You are free to alter those props if you want full control after setting sensible defaults!
Let's now go through and add our table and global secondary indexes.
Instantiating the table
We want to invoke dynamodb.Table to create an instance of a table and pass sensible props for that table.
We will also assign that instance to a publicly available accessor dynamoTable so that the consumer has access to the table when creating our construct within a stack.
Perfect! We have successfully constructed our DynamoDB table onto LocalStack.
Teardown
As always, we will also teardown the stack:
npm run local destroy
> aws-cdk-with-typescript-foundations@0.1.0 local
> cdklocal "destroy"
Are you sure you want to delete: AwsCdkWithTypescriptFoundationsStack (y/n)? y
AwsCdkWithTypescriptFoundationsStack: destroying...
✅ AwsCdkWithTypescriptFoundationsStack: destroyed
Summary
Today's post demonstrated how to create a single-table design DynamoDB table using the AWS TypeScript CDK. It did this by first creating a reusable construct, then followed it up by demonstrating usage of it in an app by deploying to LocalStack.
Tomorrow's post (as part two) will demonstrate this table in action with DynamoDB Toolbox.