William Cheng 2d7cc778db
Add a new NodeJS Express server generator (#3567)
* create nodejs express esrver

* 1st commit of the express.js module. Express server working, api-docs loads properly. No real paths yet

* 1st commit of the express.js module. Express server working, api-docs loads properly. No real paths yet (#2839)

* Working Express server with successful routing to controllers.

* rewrote controllers and services. Haven't tested yet

* controllers and services have passed tests successfully

* Added documentation

* Added documentation

* Support for openApi v3, using 'express-openapi-validator' for parsing and validation, and an internal router to pass arguments to controllers and services. /controllers/Pet.js and /services/PetService.js should be used for reverse engineering for future codegen script

* update generator and template

* update samples

* more update

* update service, controller

* add vendor extensions

* some updates to adapt to changes in the generator (removing references to swager); some work on handling file uploads; some work on tests

* Update NodeJS server generator and templates based on new output (#3261)

* update generator and template

* update samples

* more update

* update service, controller

* add vendor extensions

* update doc

* Changed routing code to follow the following convention:
Each path operation has a 'x-openapi-router-controller' and 'x-openapi-router-service'. Automated files will be placed under /controllers and /services respectively.
Controller file names will end with 'Controller.js'.
Removed swaggerRouter, replaced it with openapiRouter
Routing works and simple tests show a return of 200 to requests.

* [nodejs-express-server] various updates, fixes (#3319)

* various fix

* remove dot from service

* add space

* better method empty argument

* remove test service (#3379)

* add new doc

* 1. routingTests.js runs through all operations described in openapi.yaml and tries calling them, expecting 200 in return. Currently not all tests pass - not supporting xml, and problems with formData
2. Removed old testing files.
3. Added model files - contain data and structure as defined in openapi.yaml. Model.js has static methods relevant to all model files.
4. Changed openapi.yaml to allow running tests easily.

* 1. routingTests.js runs through all operations described in openapi.yaml and tries calling them, expecting 200 in return. Currently not all tests pass - not supporting xml, and problems with formData (#3442)

2. Removed old testing files.
3. Added model files - contain data and structure as defined in openapi.yaml. Model.js has static methods relevant to all model files.
4. Changed openapi.yaml to allow running tests easily.

* added model classes. Currently as a concept only. Seems like won't be in use

* Updated README.md to be a detailed description of the project.
Removed test files that are not needed.
Removed utils/writer.js which is not needed, and the references to it in the codegen files

* Removed redundant file app.js - this file has no benefit at this point. index.js now calls ExpressServer.js directly. Updated files that used to call app.js. Updated README.md accordingly
Added a path to call the openapi.yaml, and a test file for all endpoints that are not in the openapi.yaml, ensuring that they return 200. Updated README.md accordingly

* Remove test controller (#3575)

* remove test controller

* add back changes to templates

* remove app.js

* update wording
2019-08-09 00:30:47 +08:00

94 lines
2.8 KiB
JavaScript

// const { Middleware } = require('swagger-express-middleware');
const path = require('path');
const swaggerUI = require('swagger-ui-express');
const yamljs = require('yamljs');
const express = require('express');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const { OpenApiValidator } = require('express-openapi-validator');
const openapiRouter = require('./utils/openapiRouter');
const logger = require('./logger');
class ExpressServer {
constructor(port, openApiYaml) {
this.port = port;
this.app = express();
this.openApiPath = openApiYaml;
this.schema = yamljs.load(openApiYaml);
this.setupMiddleware();
}
setupMiddleware() {
// this.setupAllowedMedia();
this.app.use(cors());
this.app.use(bodyParser.json());
this.app.use(express.json());
this.app.use(express.urlencoded({ extended: false }));
this.app.use(cookieParser());
this.app.use('/spec', express.static(path.join(__dirname, 'api')));
this.app.get('/hello', (req, res) => res.send('Hello World. path: '+this.openApiPath));
// this.app.get('/spec', express.static(this.openApiPath));
this.app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(this.schema));
this.app.get('/login-redirect', (req, res) => {
res.status(200);
res.json(req.query);
});
this.app.get('/oauth2-redirect.html', (req, res) => {
res.status(200);
res.json(req.query);
});
new OpenApiValidator({
apiSpecPath: this.openApiPath,
}).install(this.app);
this.app.use(openapiRouter());
this.app.get('/', (req, res) => {
res.status(200);
res.end('Hello World');
});
}
addErrorHandler() {
this.app.use('*', (req, res) => {
res.status(404);
res.send(JSON.stringify({ error: `path ${req.baseUrl} doesn't exist` }));
});
/**
* suppressed eslint rule: The next variable is required here, even though it's not used.
*
** */
// eslint-disable-next-line no-unused-vars
this.app.use((error, req, res, next) => {
const errorResponse = error.error || error.errors || error.message || 'Unknown error';
res.status(error.status || 500);
res.type('json');
res.json({ error: errorResponse });
});
}
async launch() {
return new Promise(
async (resolve, reject) => {
try {
this.addErrorHandler();
this.server = await this.app.listen(this.port, () => {
console.log(`server running on port ${this.port}`);
resolve(this.server);
});
} catch (error) {
reject(error);
}
},
);
}
async close() {
if (this.server !== undefined) {
await this.server.close();
console.log(`Server on port ${this.port} shut down`);
}
}
}
module.exports = ExpressServer;