Define resources

Add resources to the hit counter construct #

Now, let’s define the AWS Lambda function and the DynamoDB table in our HitCounter construct. Go back to hitcounter/hitcounter.go and add the following highlighted code:

package hitcounter

import (
	"github.com/aws/aws-cdk-go/awscdk/v2/awsdynamodb"
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type HitCounterProps struct {
	Downstream awslambda.IFunction
}

type hitCounter struct {
	constructs.Construct
	handler awslambda.IFunction
}

type HitCounter interface {
	constructs.Construct
	Handler() awslambda.IFunction
}

func NewHitCounter(scope constructs.Construct, id string, props *HitCounterProps) HitCounter {
	this := constructs.NewConstruct(scope, &id)

	table := awsdynamodb.NewTable(this, jsii.String("Hits"), &awsdynamodb.TableProps{
		PartitionKey: &awsdynamodb.Attribute{Name: jsii.String("path"), Type: awsdynamodb.AttributeType_STRING},
	})

	handler := awslambda.NewFunction(this, jsii.String("HitCounterHandler"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_16_X(),
		Handler: jsii.String("hitcounter.handler"),
		Code:    awslambda.Code_FromAsset(jsii.String("lambda"), nil),
		Environment: &map[string]*string{
			"DOWNSTREAM_FUNCTION_NAME": props.Downstream.FunctionName(),
			"HITS_TABLE_NAME":          table.TableName(),
		},
	})

	return &hitCounter{this, handler}
}

func (h *hitCounter) Handler() awslambda.IFunction {
	return h.handler
}

What did we do here? #

This code is hopefully quite easy to understand:

  • We defined a DynamoDB table with path as the partition key.
  • We defined a Lambda function which is bound to the lambda/hitcounter.handler code.
  • We wired the Lambda’s environment variables to the FunctionName and TableName of our resources.

Late-bound values #

The FunctionName and TableName properties are values that only resolve when we deploy our stack (notice that we haven’t configured these physical names when we defined the table/function, only logical IDs). This means that if you print their values during synthesis, you will get a “TOKEN”, which is how the CDK represents these late-bound values. You should treat tokens as opaque strings. This means you can concatenate them together for example, but don’t be tempted to parse them in your code.

We use analytics to make this content better, but only with your permission.

More information