skip to Main Content

Bear with me as I am learning Lambda. I have a simple collection in DynamoDB with this model

{
  id: String,
  question: String,
  answer: String,
  learned: Boolean
}

And my Lambda function like this (With the help of an AWS Employee)

import { DynamoDBClient, ScanCommand } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient({});

export const handler = async function(event, context, callback) {
  
const command = new ScanCommand({
    TableName: "Vocabulary",
  });

  const response = await client.send(command);

  response.Items.forEach(function (item) {
    console.log(`${item}`);
  });
  return response;
};

This gives me a successful response but it’s a weird one! Looks like this

{
  "question": {
    "S": "What is the name of your Judo organization?"
  },
  "learned": {
    "BOOL": false
  },
  "Id": {
    "S": "2"
  },
  "answer": {
    "S": "United States Judo Association"
  }
}

Is this a misconfiguration on my table in DynamoDB or do I need to rework my Lambda to give me a different response. I was expecting

{
  "question":  "What is the name of your Judo organization?",
  "learned":  false,
  "Id": "2",
  "answer": "United States Judo Association"
}

Thanks for your help.

EDIT

Maybe I wasn’t too clear. I’m not interested in returning the datatype in my response. I’m only interested in the key value pair. Unless, in my ignorance, this is something that is only visible in a Lambda test but the actual json API will not contain it. Is that the case. Like I said, guys, I’m very new at this. I’m learning

2

Answers


  1. To get the output you’d like would be pretty straight forward if not super flexible. Something like (untested):

    import { DynamoDBClient, ScanCommand } from "@aws-sdk/client-dynamodb";
    
    const client = new DynamoDBClient({});
    
    export const handler = async function(event, context, callback) {
      
        const command = new ScanCommand({
            TableName: "Vocabulary",
        });
    
        const response = await client.send(command);
        var container = {};
    
        response.Items.forEach(function (item) {
            var itemData = {
                Id: item.id.S
                question: item.question.S
                answer: item.answer.S
                learned: item.learned.BOOL
            };
    
            container.push(itemData);
        });
    
        // container is an array of the items you want
    }
    

    The downside is that you’re hard coding the column names here. As a NoSQL database each row could have a variable number of columns and you’re not accounting for that. That would take a describeTable call but let’s see if this is what you’re looking for currently.

    Login or Signup to reply.
  2. The type descriptors you are seeing are because you use the low level client, which returns DynamoDB JSON. If you would like native JSON then you need to use the Document Client.

    const { DynamoDBClient } = require(“@aws-sdk/client-dynamodb”);
    const { DynamoDBDocumentClient, ScanCommand } = require(“@aws-sdk/lib-dynamodb”);
    
    const client = new DynamoDBClient({});
    const docClient = DynamoDBDocumentClient.from(client);
    
    export const handler = async function(event, context, callback) {
      
    const command = new ScanCommand({
        TableName: "Vocabulary",
      });
    
      const response = await docClient.send(command);
    
      response.Items.forEach(function (item) {
        console.log(`${item}`);
      });
      return response;
    };
    

    The Document client works for both reading and writing, meaning you can read and update items using native JSON and not think about the DynamoDB low level JSON.

    You can read more about it from my blog here:

    https://aws.amazon.com/blogs/database/exploring-amazon-dynamodb-sdk-clients/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search