OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.74k stars 6.56k forks source link

[BUG] Node Express Server Generator Uses Older Version of Express-OpenAPI-Validator this Does Not Work with NodeJS 16 #11568

Open davesargrad opened 2 years ago

davesargrad commented 2 years ago

Bug Report Checklist

The current node express generator is still using an older (3.x) version of the express-openapi-validator "express-openapi-validator": "^3.9.1",

I've seen online that this is not compatible with node 16.

I saw this problem when I was trying to isolate the following (see picture at bottom of issue) curl error (generated by the underlying express-openapi-validator).

This issue suggests that the solution is to migrate to version 4.

The latest version of the validator is 4.13.5.

What is the plan to update the openapi express server generator to use the latest version of the validator?

image

davesargrad commented 2 years ago

I've verified that the generated code works when I downgrade to NodeJS 14.

spoyd commented 2 years ago

I got a simple example from the nodejs-express-server generator to run with Node.js 16.13.2. I did this by manually editing the generated files, but I documented the changes in a fork of this repository. I'm on deadline, so I might not get to the pull request right away. However, the changes from my fork might help you to get your code working.

https://github.com/spoyd/openapi-generator/commit/7119c9aa82bdde728cb9bebb8cbcec480d519f89

davesargrad commented 2 years ago

I got a simple example from the nodejs-express-server generator to run with Node.js 16.13.2. I did this by manually editing the generated files, but I documented the changes in a fork of this repository. I'm on deadline, so I might not get to the pull request right away. However, the changes from my fork might help you to get your code working.

spoyd@7119c9a

Thats awesome. I've been monitoring this issue for a while. I've been hoping that the OpenAPI Tools team would update their nodejs generator to use the latest validator.

I have wondered how active this OpenAPITools project is, given that this framework issue seems to be a long-standing concern.

I'll take a look at your fork. Thanks for the guidance.

davesargrad commented 2 years ago

I got a simple example from the nodejs-express-server generator to run with Node.js 16.13.2. I did this by manually editing the generated files, but I documented the changes in a fork of this repository. I'm on deadline, so I might not get to the pull request right away. However, the changes from my fork might help you to get your code working.

spoyd@7119c9a

What is the process, from your perspective, to get the OpenAPITools team to integrate whatever it is that you did? I dont really understand how that lifecycle works.

ryan-roberts commented 1 year ago

I got a simple example from the nodejs-express-server generator to run with Node.js 16.13.2. I did this by manually editing the generated files, but I documented the changes in a fork of this repository. I'm on deadline, so I might not get to the pull request right away. However, the changes from my fork might help you to get your code working.

https://github.com/spoyd/openapi-generator/commit/7119c9aa82bdde728cb9bebb8cbcec480d519f89

@spoyd Where is that set of changes now? The link unfortunately currently results in a github 404.

ankurmittalkellton commented 1 year ago

This URL is not working https://github.com/spoyd/openapi-generator/commit/7119c9aa82bdde728cb9bebb8cbcec480d519f89 Please share the changes, It will be helpful for others also.

wilml commented 7 months ago

This is still present for openapi-generator v7.4.0 using latest node LTS v20.11

dsdrudge commented 7 months ago

I also ran into this and am looking for generated code changes.

wilml commented 7 months ago

Ok this is what I did in order to get it working with Node.js v20.x and express-openapi-validator v4.x hopefully this helps others.

Update packages

Uninstall existing express-openapi-validator module,

npm uninstall express-openapi-validator

Install the updated validator,

npm install express-openapi-validator@4.13.8

Update expressServer.js

How express-openapi-validator is isntalled changed in v4, update launch in expressServer.js to be,

llaunch(){
  // eslint-disable-next-line no-unused-vars
  this.app.use((err, req, res, next) => {
    // format errors
    res.status(err.status || 500).json({
      message: err.message || err,
      errors: err.errors || '',
    });
  });

then add the following to the bottom of setupMiddleware() in expressServer.js,

this.app.use(
      OpenApiValidator.middleware({
        apiSpec: this.openApiPath,
        operationHandlers: path.join(__dirname),
      }),
    );

Update controllers/Controller.js

The return values in v4 of express-openapi-validator changed in v4 so we need to update Controller.js to reflect otherwise you'll get errors. See this comment on the changes to make. For convience update collectRequestParams to,

  static collectRequestParams(request) {
    const requestParams = {};
    if (request.openapi.schema.requestBody !== null) {
      const { content } = request.openapi.schema.requestBody;
      if (content['application/json'] !== undefined) {
        const requestBodyName = camelCase(this.getRequestBodyName(request));
        requestParams[requestBodyName] = request.body;
      } else if (content['multipart/form-data'] !== undefined) {
        Object.keys(content['multipart/form-data'].schema.properties).forEach(
          (property) => {
            const propertyObject = content['multipart/form-data'].schema.properties[property];
            if (propertyObject.format !== undefined && propertyObject.format === 'binary') {
              requestParams[property] = this.collectFile(request, property);
            } else {
              requestParams[property] = request.body[property];
            }
          },
        );
      }
    }

    if (request.openapi.schema.parameters !== undefined) {
      request.openapi.schema.parameters.forEach((param) => {
        if (param.in === 'path') {
          requestParams[param.name] = request.openapi.pathParams[param.name];
        } else if (param.in === 'query') {
          requestParams[param.name] = request.query[param.name];
        } else if (param.in === 'header') {
          requestParams[param.name] = request.headers[param.name];
        }
      });
    }
    return requestParams;
  }

Additional notes

If I get time I'm hoping to open a PR to integrate these changes.