Reputation: 357
My nodejs app has an open-api.yaml file and express-openapi-validate validator. I'm doing a POST request which is working and the api validator doesn't return any errors:
curl --request POST 'http://localhost:33004/my-app/settings' --data-raw '{"serials":["1234","2355"]}' -H 'Content-Type: application/json'
In my open-api.yaml I have:
openapi: '3.0.0'
servers:
- url: 'http://{host}/my-app'
variables:
host:
enum:
- 'localhost'
....
...
paths:
/settings:
...
post:
tags:
- 'settings'
operationId: 'postSettings'
requestBody:
content:
application/json:
schema:
type: object
properties:
serials:
type: array
items:
type: string
...
Then I tried dockerizing my app - created a docker container, and ran it inside with the pm2-runtime. However, when I send the same request to the docker container when the app is running in it, I get error while validating request: request should have required property '.headers'
. I have no property '.headers' mentioned in the open-api.yaml file.
I tried removing the validator middleware, and the request went through just fine. Can you help me understand what is the validator complaining about?
EDIT:
I managed to find the error object:
{
"data": [
{
"dataPath": "",
"keyword": "required",
"message": "should have required property '.headers'",
"params": {
"missingProperty": ".headers"
},
"schemaPath": "#/required"
}
],
"name": "ValidationError",
"statusCode": 400
}
needless to say I have no required headers property...
Upvotes: 9
Views: 14535
Reputation: 39
Might be a little late but hopefully will be useful for others.
The problem is related to this code (this is the compiled version)
...
const reqToValidate = Object.assign({}, req, { cookies: req.cookies
? Object.assign({}, req.cookies, req.signedCookies) : undefined });
const valid = validator(reqToValidate);
...
on OpenApiValidator and the fact that Express req
object use accessor get/set for headers, as a result Object.assign will not propagate headers information and consequenlty the validator
function will not find the required headers properties, only rawHeaders is available.
As a quick fix I implemented the following:
const validator = this.openApiValidator.validate(method, path);
return (req, res, next) => {
const reqToValidate = Object.assign({}, req, {
cookies: req.cookies
? Object.assign({}, req.cookies, req.signedCookies) : undefined
});
if (!reqToValidate.hasOwnProperty('headers')) {
reqToValidate.headers = req.headers;
}
return validator(reqToValidate, res, next);
};
which adapts Express request and propagate all required information regarding headers.
Upvotes: 3
Reputation: 1748
I had the same for all node versions <= 14 and for express-openapi-validator version <= 3.
Impossible to have the validator working with node version 16 and we were stuck to an old dev version because of it.
The solution was to migrate to express-openapi-validator v4.
The migration is explained here https://github.com/cdimascio/express-openapi-validator#upgrading-from-3x
This (v3):
const validator = new OpenApiValidator({
apiSpec: openApiYaml,
operationHandlers: __dirname
})
app.use(validator)
becomes (v4):
const validator = OpenApiValidator.middleware({
apiSpec: 'src/openapi.yaml'
})
app.use(validator)
The code was originally generated by https://hub.docker.com/r/openapitools/openapi-generator-cli
Upvotes: 7
Reputation: 357
For future reference if others come here for this problem:
I finally found the issue: I was using FROM node:alpine
in my Dockerfile, which indicates the latest version of node. However, my application was running on node 10.18.1
Once I changed to FROM:node:10.18.1-alpine
the issue was resolved.
Apparently, the express-openapi-validate plugin has some issues in the latest node module, or so it seems.
Upvotes: 1