express-openapi-validator icon indicating copy to clipboard operation
express-openapi-validator copied to clipboard

Error while validating array of objects

Open sunnyofhell opened this issue 3 years ago • 2 comments

Describe the bug Gives a 400 bad error, query parameter containing arrays of objects

To Reproduce "express-openapi-validator": "^4.4.3", With the following Swagger YAML

parameters:
      - name: request
        in: query
        description: Deep object request body
        required: true
        style: deepObject
        explode: true
        allowReserved: true
        schema:
          type: array
          items: 
            type: object
            properties:
              name :
                type : string
              age :
                type : string

Actual behavior The request fails with the following error message

{
  "message": "request.query.request[0] should be object, request.query.request[1] should be object",
  "errors": [
    {
      "path": ".query.request[0]",
      "message": "should be object",
      "errorCode": "type.openapi.validation"
    },
    {
      "path": ".query.request[1]",
      "message": "should be object",
      "errorCode": "type.openapi.validation"
    }
  ]
}

Expected behavior Should have passed and not resulted in a validation failure

Request: Two times using the add object, button in swagger UI

{
  "name": "string",
  "age": "string"
}

sunnyofhell avatar Jun 17 '22 13:06 sunnyofhell

I'm also having this issue. I use the default style (form) and explode (true). In the debugger, I see that when RequestParameterMutator.explodeJsonArrayAndMutateRequest() is called, query[param-name] is an array of strings. The array was probably already created by express? Anyway, the array values are nowhere JSON.parse()d.

I've also tested with explode=false, but the same thing happens. parseJsonArrayAndMutateRequest() likewise doesn't call JSON.parse() anywhere.

databu avatar Feb 27 '23 12:02 databu

I've worked around the issue by putting in this ugly hack:

// Dirty workaround to this problem: https://github.com/cdimascio/express-openapi-validator/issues/743
// A slightly better workaround would be to do this will all array query parameters according to the
// schema. However, we might also refactor the API to avoid (arrays of) objects altogether, so I'm not putting 
// in this effort now.
app.use((req, res, next) => {
    const targetCriterias = req.query.targetCriterias;
    if(req.query.targetCriterias) {
        req.query.targetCriterias = targetCriterias instanceof Array
            ? targetCriterias.map(JSON.parse)
            : JSON.parse(req.query.targetCriterias);
    }
    next();
});

databu avatar Feb 28 '23 04:02 databu