How do I check if an item with same name already exist in AWS Lambda function using DynamoDB

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

Answers (1)

Leeroy Hannigan
Leeroy Hannigan

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

Related Questions