Skip to main content

Lambda Person Request DynamoDB

Description

lambda-person-request-dynamodb-01.png

Prerequisites

Start LocalStack via Docker Compose

version: '3.8'

services:
localstack:
image: localstack/localstack
container_name: localstack_main
ports:
- "4566-4599:4566-4599"
environment:
- SERVICES=sns,s3,sqs,dynamodb,ses,lambda,logs,stepfunctions
- DYNAMODB_SHARE_DB=1
- DEBUG=1
- DATA_DIR=/tmp/localstack/data
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"

Create DynamoDB Table

awslocal dynamodb create-table \
--table-name person \
--key-schema AttributeName=id,KeyType=HASH \
--attribute-definitions AttributeName=id,AttributeType=N \
--billing-mode PAY_PER_REQUEST

Prepare Lambda Code

Source Code:
https://github.com/ZbCiok/zjc-examples/tree/main/aws/aws/lambda/lambda-person-request-dynamodb

  • Project Structure

├── cmds.txt
├── pom.xml
├── README.md
└── src
└── main
├── java
│   └── v2
│   └── dynamodb
│   ├── PersonRequest.java
│   ├── PersonResponse.java
│   └── SavePersonHandler.java
└── resources
  • PersonRequest.java

package v2.dynamodb;

import lombok.NoArgsConstructor;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;

@NoArgsConstructor
@DynamoDbBean
public class PersonRequest {

private int id;
private String firstName;
private String lastName;
private int age;
private String address;

@DynamoDbPartitionKey
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "PersonRequest{" +
"address='" + address + '\'' +
'}';
}
}
  • PersonResponse.java

package v2.dynamodb;

import lombok.NoArgsConstructor;


@NoArgsConstructor
public class PersonResponse {
private String message;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}


@Override
public String toString() {
return "PersonResponse{" +
"message='" + message + '\'' +
'}';
}
}
  • SavePersonHandler

package v2.dynamodb;

import java.text.ParseException;
import java.net.URI;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import lombok.extern.java.Log;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

@Log
public class SavePersonHandler implements RequestHandler<PersonRequest, PersonResponse> {

private static final String ACCESS_KEY = "test";
private static final String SECRET_KEY = "test";
private static String TABLE_NAME = "person";
private static AwsCredentialsProvider credentials = StaticCredentialsProvider.create(
AwsBasicCredentials.create(ACCESS_KEY, SECRET_KEY));

private static Region region = Region.US_EAST_1;

private static DynamoDbClient dynamoDbClient = DynamoDbClient.builder()
.region(region)
.credentialsProvider(credentials)
.endpointOverride(URI.create("https://localhost.localstack.cloud:4566"))
.build();

// -----

public PersonResponse handleRequest(PersonRequest personRequest, Context context) {
log.info("Start handleRequest >>>");

String personId1 = "300012356";
try {
addEntryToDynamoDB(personId1);
} catch (Exception e) {
log.info("Exception handleRequest >>> " + e.getMessage());
}

PersonResponse personResponse = new PersonResponse();
personResponse.setMessage("Success >>> Add Entry Successfully!!!");
return personResponse;
}

private static void addEntryToDynamoDB(String personID) throws ParseException {
try {
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(dynamoDbClient)
.build();

// create the person object
PersonRequest person = new PersonRequest();
person.setId(Integer.parseInt(personID));
person.setFirstName("Doe");
person.setLastName("John");
person.setAge(Integer.parseInt("19790101"));
person.setAddress("Address 01");

// use the enhanced client to interact with the table
DynamoDbTable<PersonRequest> table = enhancedClient.table(TABLE_NAME,
TableSchema.fromBean(PersonRequest.class));
table.putItem(person);

log.info(">>> Add Entry successfully");
} catch (DynamoDbException exception) {
log.info(">>> Add Entry an error occurred: " + exception.getMessage());
}
}

}
  • Deploy Lambda Function

    • mvn clean package

    • Create Function

    awslocal lambda create-function \
    --function-name example-lambda \
    --runtime java21 \
    --handler v2.dynamodb.SavePersonHandler::handleRequest \
    --zip-file fileb://lambda-person-request-dynamodb-1.0-SNAPSHOT.jar \
    --role arn:aws:iam::000000000000:role/lambda-role

Test Lambda

awslocal lambda invoke --function-name example-lambda \
--cli-binary-format raw-in-base64-out \
--payload '{ "name": "John Doe", "question": "How are you?" }' output.txt

Output

  • See Docker Log
  • See DynamoDB table:
     awslocal dynamodb query \
    --table-name person \
    --key-condition-expression "id = :id" \
    --expression-attribute-values '{":id":{"N":"300012356"}}'
{
"Items": [
{
"firstName": {
"S": "John"
},
"lastName": {
"S": "Doe"
},
"address": {
"S": "Address01"
},
"id": {
"N": "1"
},
"age": {
"N": "26"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}