Home > front end >  AWS Serverless Lambda Java retrieve all items from Amazon DynamoDB without variable types
AWS Serverless Lambda Java retrieve all items from Amazon DynamoDB without variable types

Time:07-19

I have written a lambda function that scans all items in dynamoDB but it retrieves them with its types. How can I remove them? Should I try to parse data in an appropriate way for me or there is a better way of doing it?

public class Get implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    DynamoDB dynamoDB = new DynamoDB(client);
    ScanRequest scanRequest = new ScanRequest()
            .withTableName("xxx");

    static final int STATUS_CODE_NO_CONTENT = 204;
    static final int STATUS_CODE_CREATED = 201;
    static final int STATUS_CODE_FAILED = 400;
    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent request, Context context) {
        Map<String, String> map = request.getPathParameters();
        ContactDetails contactDetails = null;
        APIGatewayProxyResponseEvent response = null;
        int code = STATUS_CODE_NO_CONTENT;
        try {
            ScanResult result = client.scan(scanRequest);
            code = STATUS_CODE_CREATED;
            response = new APIGatewayProxyResponseEvent().withStatusCode(code).withIsBase64Encoded(Boolean.FALSE).withHeaders(Collections.emptyMap()).withBody(new Gson().toJson(result.getItems()));
        } catch (Exception e) {
            code = STATUS_CODE_FAILED;
            response = new APIGatewayProxyResponseEvent().withStatusCode(code).withIsBase64Encoded(Boolean.FALSE).withHeaders(Collections.emptyMap()).withBody(e.toString());
        }
        return response;
    }
}

response: [{"kontent":{"s":"ys"},"id":{"s":"ys"}},{"id":{"s":"asdassa"}}] need to make it [{"id":"ys", "kontent": "ys"}, {"id":"asdassa"}]

CodePudding user response:

There is definetly a better way of performing Amazon DynamoDB CRUD operations from within an AWS Lambda functions.

Move away from AWS SDK for Java V1 to V2. Amazon Strongly encourages devs to use V2 when using the JAVA SDK and the Enhanced Client to perform Amazon DynamoDB CRUD operations.

software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient

For details, see:

https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html

This client works nicely witin an AWS Lambda function. For details on how to use this client witin an AWS Lambda Function that uses the Java run-time Lambda API, see this article:

Creating an AWS Lambda function that detects images with Personal Protective Equipment

This example creates a Java Lambda function that detects PPE information in the image using the Amazon Rekognition service and creates a record in an Amazon DynamoDB table. This shows you best practice to perform CRUD operations from wihtin a Lambda fuction using the Enhanced Client.

UPDATE

When you use the Enchanced Client and a Scan operation, the Scan method returns Java Objects. You do NOT HAVE TO use logic like you do with V1 and getItems. That is one of the best parts of using this client.

To get the data, you simply call the method that belongs to the Java object. For example, here is a Scan method returning Customer objects, To get the data, you simply call methods that belong to a Customer object - for example, getCustName():

public static void scan( DynamoDbEnhancedClient enhancedClient) {
        try{
            DynamoDbTable<Customer> custTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
            Iterator<Customer> results = custTable.scan().items().iterator();
            while (results.hasNext()) {
                Customer rec = results.next();
                System.out.println("The record id is " rec.getId());
                System.out.println("The name is "  rec.getCustName());
            }

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        System.out.println("Done");
    }

CodePudding user response:

You need to unwrap the AttributeValue instances that are returned from result.getItems(). Simple for a string, but there are more complex data types too.

Implement this method, then wrap result.getItems() with it, i.e. convertItems(result.getItems())

List<Map<String, Object>> convertItems(List<Map<String, AttributeValue>> items) {
    List<Map<String, Object>> newItems = new ArrayList<>(items.size());
    for (Map<String, AttributeValue> item : items) { 
        Map<String, Object> newItem = new HashMap<>();
        item.forEach((key, value) -> {
            switch(value.type()) {
                case S:
                    newItem.put(key, value.s());
                    break;
                // Any other types you want to support besides string
            }
        });
        newItems.add(newItem);
    }
    return newItems;
}
  • Related