Home > Software engineering >  Put items in DynamoDB without knowing the attributes
Put items in DynamoDB without knowing the attributes

Time:04-12

This feels like a really stupid question, but my lack of JS knowledge combined with lack of AWS knowledge has me in a tight spot! I'm just trying to get to grips with a basic AWS stack i.e. Lambda/Dynamo/API Gateway for some basic API work.

If I want a simple API endpoint to handle PUT requests e.g. https://my.endpoint.amazonaws.com/users. If I have a DynamoDB table with a composite primary key of userID and timestamp I could use the code snippet below to take the unknown data (attributes that weren't known when setting a schema), but this obviously doesn't work well

const dynamo = new AWS.DynamoDB.DocumentClient();
let requestJSON = JSON.parse(event.body);
await dynamo
  .put({
    TableName: "myDynamoTable",
    Item: {
      userID: requestJSON.userID,
      timestamp: requestJSON.timestamp,
      data: requestJSON.data
    }
  })
.promise();

I could send a PUT request with the following JSON

{
    "userID": "aaaa1111",
    "timestamp": 1649677057,
    "data": {
        "address": "Elm Street",
        "name": "Glen"
    }
}

but then address and name get shoved into a single DynamoDB attribute named data. How do I construct the node code to create a new attribute named address and one named name with the corresponding values, if I didn't know these attributes i.e. I want to use JSON in my request like below, but assuming I don't know this and can't use requestJSON.address

{
    "userID": "aaaa1111",
    "timestamp": 1649677057,
    "address": "Elm Street",
    "name": "Glen"
}

CodePudding user response:

If you insist on the API contract as

{
    "userID": "aaaa1111",
    "timestamp": 1649677057,
    "data": {
        "address": "Elm Street",
        "name": "Glen"
    }
}

then you can do mapping on the TypeScript level

const request: {userID: string, timestamp: number, data: any} = {
    "userID": "aaaa1111",
    "timestamp": 1649677057,
    "data": {
        "address": "Elm Street",
        "name": "Glen"
    }
};

const ddbObject: any = {
    "userID": request.userID,
    "timestamp": request.timestamp
};

Object
    .keys(request.data)
    .forEach(key => ddbObject[key] = request.data[key]);

Representation of ddbObject is

{
  "userID": "aaaa1111",
  "timestamp": 1649677057,
  "address": "Elm Street",
  "name": "Glen"
} 

CodePudding user response:

You can use the spread operator, for example:

const data = {
  address: "Elm Street",
  name: "Glen",
};

const item = {
  userID: "aaaa1111",
  timestamp: 1649677057,
  ...data,
};

console.log("item:", item);

  • Related