6

I am trying to fetch all records using query and JSON schema but I am keep getting Event object failed validation unless I pass a query it didn't give me any result. I am trying to fetch all the records that have status=OPEN I set the default value of status=OPEN but it looks like default value is working. Unless I pass the status=OPEN as a query Please help me!!!

And used @middy/validator for this case anyone it's been 2 days I still can't figured out the problem

JSON Schema file

const getAuctionsSchema = {
    type: 'object',
    required: ['queryStringParameters'],
    properties: {
        queryStringParameters: {
            type: 'object',
            required: ['status'],
            properties: {
                status: {
                    default: 'OPEN',
                    enum: ['OPEN', 'CLOSED'],
                },
            },
        },
    },
};

module.exports = getAuctionsSchema;

Here all records fetch file

const AWS = require('aws-sdk');
const createError = require('http-errors');
const validator = require('@middy/validator');
const commonMiddleware = require('../lib/commonMiddleware');
const getAuctionsSchema = require('../lib/schemas/getAuctionsSchema');

const dynamoDB = new AWS.DynamoDB.DocumentClient();

const get_auctions = async (event) => {
    const { status } = event.queryStringParameters;
    let auctions;

    const params = {
        TableName: process.env.AUCTIONS_TABLE_NAME,
        IndexName: 'statusAndEndDate',
        KeyConditionExpression: '#status = :status',
        ExpressionAttributeValues: {
            ':status': status,
        },
        ExpressionAttributeNames: {
            '#status': 'status',
        },
    };

    try {
        const result = await dynamoDB.query(params).promise();

        auctions = result.Items;
    } catch (err) {
        console.log(err);
        throw new createError.InternalServerError(err);
    }

    return {
        statusCode: 200,
        body: JSON.stringify(auctions),
    };
};

module.exports = {
    handler: commonMiddleware(get_auctions).use(
        validator({
            inputSchema: getAuctionsSchema,
            ajvOptions: {
                useDefaults: true,
                strict: false,
            },
        })
    ),
};

Here is the error I can see in Cloud Watch

ERROR   BadRequestError: Event object failed validation
at createError (/var/task/node_modules/@middy/util/index.js:259:10)
    at validatorMiddlewareBefore (/var/task/node_modules/@middy/validator/index.js:55:21)
    at runMiddlewares (/var/task/node_modules/@middy/core/index.js:120:88)
    at async runRequest (/var/task/node_modules/@middy/core/index.js:80:5) {
  details: [
    {
      instancePath: '',
      schemaPath: '#/required',
      keyword: 'required',
      params: [Object],
      message: 'must have required property queryStringParameters'
    }
  ]
}
Developer Nans
  • 311
  • 1
  • 4
  • 14
  • What was the URL that your client requested? Did it have any query parameters? – jarmod Feb 03 '22 at 14:15
  • @jarmod Yes there is query parameter called OPEN and CLOSED. To be accurate my problem is that i want query parameter should be default OPEN like if i don't pass any query the default query should be OPEN that's what I want if pass the query its working but want if I don't pass anything the default query should work – Developer Nans Feb 03 '22 at 17:16
  • You misread my question. It seems that you want an optional query parameter named `status` (whose default value will be OPEN) but in your actual test you did not provide any query parameters and hence you failed the schema validation per the answer below. – jarmod Feb 03 '22 at 17:36
  • @jarmod I don't know much about because I am still learning. Yes maybe you are right can you tell mw how to do If I don't pass status as a query like physically typing but it still it still gonna status=OPEN as a default query – Developer Nans Feb 05 '22 at 06:45
  • You first have to resolve the schema validation problem if you want to allow no query parameters so try the suggestion in the @eli6 answer. – jarmod Feb 05 '22 at 15:47
  • @DeveloperNans I added an example in my answer for how you can set the status value to open, even if queryStringParameter is null in the query. Please see the 'EDIT' below. – eli6 Feb 07 '22 at 10:00

1 Answers1

5

The validator is expecting a queryStringParameters property of type object. According to the JSON Schema Specification for Objects, if a property is declared as having a certain type, that property fails validation if it is has a different type.

If you don't pass any query parameters to Api Gateway (in a Lambda Proxy integration), queryStringParameters will be null, but you have specified that it must be an object and null is not an object.

It is possible to specify several allowed types in the Schema: type: ['object', 'null']. You can read more about using several types here.


EDIT: To be able to set status to 'OPEN' even when queryStringParameters is null in the query, you can give queryStringParameters a default value (an object), with status set to 'OPEN'):

const getAuctionsSchema = {
    type: 'object',
    required: ['queryStringParameters'],
    properties: {
        queryStringParameters: {
            type: 'object',
            required: ['status'],
            default: {status: 'OPEN'},
            properties: {
                status: {
                    default: 'OPEN',
                    enum: ['OPEN', 'CLOSED'],
                },
            },
        },
    },
};
eli6
  • 964
  • 5
  • 15