【问题标题】:open api error: request should have required property '.headers' - docker打开 api 错误:请求应该具有必需的属性 '.headers' - docker
【发布时间】:2021-05-30 21:42:27
【问题描述】:

我的 nodejs 应用有一个 open-api.yaml 文件和 express-openapi-validate 验证器。我正在执行一个有效的 POST 请求,并且 api 验证器没有返回任何错误:

curl --request POST 'http://localhost:33004/my-app/settings' --data-raw '{"serials":["1234","2355"]}' -H 'Content-Type: application/json'

在我的 open-api.yaml 中有:

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
...

然后我尝试 dockerizing 我的应用程序 - 创建了一个 docker 容器,并使用 pm2-runtime 在内部运行它。但是,当我在其中运行应用程序时向 docker 容器发送相同的请求时,我得到 error while validating request: request should have required property '.headers' 。我在 open-api.yaml 文件中没有提到属性“.headers”。

我尝试删除验证器中间件,请求顺利通过。你能帮我理解验证者在抱怨什么吗?

编辑:

我设法找到了错误对象:

{
  "data": [
    {
      "dataPath": "",
      "keyword": "required",
      "message": "should have required property '.headers'",
      "params": {
        "missingProperty": ".headers"
      },
      "schemaPath": "#/required"
    }
  ],
  "name": "ValidationError",
  "statusCode": 400
}

不用说我没有必需的 headers 属性...

【问题讨论】:

  • 尝试将-H "Content-Type: application/json" 添加到您的 curl 命令中。这有帮助吗?
  • 编辑了我的问题,卷曲也包含了这个标题,只是忘了在问题中添加它。它没有帮助......
  • 不确定是否重要,但 YAML 缩进已关闭 - 例如tagsoperationIdrequestBody 必须在 post 内部,而不是在它旁边。尝试在 editor.swagger.io 中验证您的 YAML。
  • copy-pasta缩进问题,代码中格式没问题

标签: node.js docker openapi pm2


【解决方案1】:

如果其他人来这里解决这个问题,供将来参考:

我终于找到了问题:我在我的 Dockerfile 中使用了FROM node:alpine,它表示 node.js 的最新版本。但是,我的应用程序在节点 10.18.1 上运行

一旦我更改为FROM:node:10.18.1-alpine,问题就解决了。

显然,express-openapi-validate 插件在最新的节点模块中存在一些问题,或者看起来如此。

【讨论】:

  • 同样的问题,这在v14.16.1对我有用
【解决方案2】:

可能有点晚了,但希望对其他人有用。

问题与这段代码有关(这是编译后的版本)

...
const reqToValidate = Object.assign({}, req, { cookies: req.cookies
                    ? Object.assign({}, req.cookies, req.signedCookies) : undefined });
const valid = validator(reqToValidate);
...

关于 OpenApiValidator 以及 Express req 对象使用访问器获取/设置标题的事实,因此 Object.assign 不会传播标题信息,因此validator 函数将找不到所需的标题属性,只有 rawHeaders可用。

作为快速修复,我实施了以下操作:

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);
};

它适应 Express 请求并传播有关标头的所有必需信息。

【讨论】:

    【解决方案3】:

    我对所有节点版本

    验证器无法使用节点版本 16,因此我们被困在旧的开发版本中。

    解决方案是迁移到 express-openapi-validator v4。

    这里解释了迁移https://github.com/cdimascio/express-openapi-validator#upgrading-from-3x

    这个(v3):

    const validator = new OpenApiValidator({
      apiSpec: openApiYaml,
      operationHandlers: __dirname
    })
    app.use(validator)
    

    成为(v4):

    const validator = OpenApiValidator.middleware({
      apiSpec: 'src/openapi.yaml'
    })
    app.use(validator)
    

    代码最初由https://hub.docker.com/r/openapitools/openapi-generator-cli生成

    【讨论】:

      猜你喜欢
      • 2021-12-25
      • 2013-01-07
      • 1970-01-01
      • 2021-06-19
      • 2021-02-25
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多