Reputation: 11
I have an application written in Lambda functions (with DynamoDB). It performs basic CRUD operations. While adding a new item, I want to check if an item with that same name exists already for the same user.
I implemented the logic below (the POST request). While testing on Postman I get the error "Query condition missed key schema element: user_group_id"
. I am actually not interested in the user_group_id cause it's only created after the group has been added.
Is there a better or special way of doing this? What I'm I not doing right?
Thanks
const AWS = require("aws-sdk");
const { v4: uuid } = require("uuid");
const dynamo = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
let body;
let statusCode = 200;
const headers = {
"Content-Type": "application/json",
};
try {
switch (event.routeKey) {
case "GET /user-groups/all/{id}":
const params1 = {
ExpressionAttributeValues: {
":s": parseInt(event.pathParameters.id, 10),
},
KeyConditionExpression: "user_id = :s",
TableName: "User-Groups",
};
body = await dynamo.query(params1).promise();
break;
case "PUT /user-groups/edit":
...
break;
case "PUT /user-groups": //THIS IS THE POST REQUEST
let requestJSON1 = JSON.parse(event.body);
//Check if the name already exists
const name_check = {
ExpressionAttributeValues: {
":u": requestJSON1.user_id,
":g": requestJSON1.user_group_name,
},
KeyConditionExpression: "user_id = :u and user_group_name = :g",
TableName: "User-Groups",
};
const name_exist = await dynamo.query(name_check).promise();
if(name_exist){
throw new Error(`This name already exist`);
}
const arr = requestJSON1.user_ids;
arr.push(requestJSON1.user_id);
const id = uuid();
if(requestJSON1.user_id && requestJSON1.user_group_name && requestJSON1.user_group_tags.length > 0 && requestJSON1.user_ids.length > 1){
body = await dynamo
.put({
TableName: "User-Groups",
Item: {
user_id: requestJSON1.user_id,
user_group_id: id,
user_group_name: requestJSON1.user_group_name,
user_group_tags: requestJSON1.user_group_tags,
user_ids: arr,
created_at: new Date().toGMTString(),
updated_at: new Date().toGMTString(),
},
})
.promise();
body = {
user_id: requestJSON1.user_id,
user_group_id: id,
user_group_name: requestJSON1.user_group_name,
user_group_tags: requestJSON1.user_group_tags,
user_ids: arr,
created_at: new Date().toGMTString(),
updated_at: new Date().toGMTString(),
};
break;
}
break;
case "DELETE /user-groups/{id}/{user_group_id}":
...
break;
default:
throw new Error(`Unsupported route: "${event.routeKey}"`);
}
} catch (err) {
statusCode = 400;
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers,
};
};
Upvotes: -1
Views: 318
Reputation: 19893
ExpressionAttributeValues: {
":u": requestJSON1.user_id,
":g": requestJSON1.user_group_name,
},
KeyConditionExpression: "user_id = :u and user_group_name = :g",
Your issue is here. You set the KeyConditionExpression to state user_id equals :u and user_group_name equals :g
However none of those are your tables partition key which is what a Query
operation expects.
This means you either need to do a Scan
with a FilterExpression or create a GSI with the keys user_id and user_group_name and do your query against your GSI.
Upvotes: 2