Skip to content

Commit

Permalink
read and assign parameters to controllers automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
HugoMario committed Feb 4, 2020
1 parent 35d74b9 commit 206d593
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 39 deletions.
12 changes: 3 additions & 9 deletions examples/petstore/controllers/Pet.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
var utils = require('../utils/writer.js');
var Pet = require('../services/PetService');

module.exports.addPet = function addPet (req, res, next) {
var body = req.body;
module.exports.addPet = function addPet (req, res, next, body) {
Pet.addPet(body)
.then(function (response) {
utils.writeJson(res, response);
Expand All @@ -14,10 +13,7 @@ module.exports.addPet = function addPet (req, res, next) {
});
};


module.exports.findPetsByStatus = function findPetsByStatus (req, res, next) {
var status = req.query.status[0];
var sessionid = req.cookies.sessionId;
module.exports.findPetsByStatus = function findPetsByStatus (req, res, next, status, sessionid) {

Pet.findPetsByStatus(status,sessionid)
.then(function (response) {
Expand All @@ -28,9 +24,7 @@ module.exports.findPetsByStatus = function findPetsByStatus (req, res, next) {
});
};

module.exports.getPetById = function getPetById (req, res, next) {

var petId = req.openapi.pathParams['petId'];
module.exports.getPetById = function getPetById (req, res, next, petId) {
Pet.getPetById(petId)
.then(function (response) {
utils.writeJson(res, response);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"debug": "^4.1.1",
"serve-static": "^1.14.1",
"express": "^4.17.1",
"express-openapi-validator": "^3.2.3",
"express-openapi-validator": "^3.6.7",
"js-yaml": "^3.13.1",
"lodash": "^4.17.15",
"morgan": "^1.9.1",
Expand Down
2 changes: 2 additions & 0 deletions src/middleware/express.app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import cookieParser = require('cookie-parser');
import bodyParser = require('body-parser');
import { SwaggerUI } from './swagger.ui';
import { SwaggerRouter } from './swagger.router';
import { SwaggerParameters } from './swagger.parameters';
import * as logger from 'morgan';
import * as fs from 'fs';
import * as jsyaml from 'js-yaml';
Expand Down Expand Up @@ -43,6 +44,7 @@ export class ExpressAppConfig {
})
.install(this.app)
.then(() => {
this.app.use(new SwaggerParameters().checkParameters());
this.app.use(new SwaggerRouter().initialize(this.routingOptions));

this.app.use((err, req, res, next) => {
Expand Down
61 changes: 61 additions & 0 deletions src/middleware/swagger.parameters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict';

import {isEmpty} from 'lodash';

export class SwaggerParameters {
checkParameters() {
const concatArrays = (array, arrayToAttach) => {
if (isEmpty(arrayToAttach)) {
return array;
}
return array.concat(arrayToAttach);
};

return (req, res, next) => {
if (!req.openapi || !req.openapi.schema || !req.openapi.schema.parameters) {
next();
return;
}
let swaggerParameters = Array<any>();
const queryParams = Array<any>();
const headerParams = Array<any>();
const cookieParams = Array<any>();
const pathParams = Array<any>();

swaggerParameters.push(req);
swaggerParameters.push(res);
swaggerParameters.push(next);

if (!isEmpty(req.body)) {
swaggerParameters.push(req.body);
}

if (!isEmpty(req.openapi.pathParams)) {
Object.keys(req.openapi.pathParams).forEach(function(key) {
pathParams.push(req.openapi.pathParams[key]);
});
}

const parameters = req.openapi.schema.parameters;
for (let i = 0; i < parameters.length; i++) {
const parameter = parameters[i];
if (parameter.in === 'query') {
queryParams.push(req.query[parameter.name]);
} else if (parameter.in === 'cookie') {
cookieParams.push(req.cookies[parameter.name]);
} else if (parameter.in === 'header') {
headerParams.push(req.headers[parameter.name]);
}
}

swaggerParameters = concatArrays(swaggerParameters, queryParams);
swaggerParameters = concatArrays(swaggerParameters, pathParams);
swaggerParameters = concatArrays(swaggerParameters, headerParams);
swaggerParameters = concatArrays(swaggerParameters, cookieParams);

req.openapi.swaggerParameters = swaggerParameters;

next();
}
}
}
50 changes: 21 additions & 29 deletions src/middleware/swagger.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ const debug = Debug("oas3-tools:routing");

export class SwaggerRouter {

getHandlerName (req) {
if (req.openapi.schema['x-swagger-router-controller']) {
return req.openapi.schema['x-swagger-router-controller'] + '_' + (req.openapi.schema.operationId ? req.openapi.schema.operationId : req.method.toLowerCase());
} else {
return req.openapi.schema.operationId;
}
}

handlerCacheFromDir(dirOrDirs: any) {
const handlerCache: object = {};
const jsFileRegex = /\.(coffee|js|ts)$/;
Expand All @@ -33,7 +25,7 @@ export class SwaggerRouter {
each(dirs, function (dir) {
each(fs.readdirSync(dir), function (file: string) {
const controllerName: string = file.replace(jsFileRegex, '');
var controller: string;
let controller: string;

if (file.match(jsFileRegex) && file.indexOf(".test.js") === -1) {
controller = require(path.resolve(path.join(dir, controllerName)));
Expand All @@ -44,7 +36,7 @@ export class SwaggerRouter {

if (isPlainObject(controller)) {
each(controller, function (value, name) {
var handlerId = controllerName + '_' + name;
let handlerId = controllerName + '_' + name;

debug(' %s%s',
handlerId,
Expand All @@ -62,12 +54,6 @@ export class SwaggerRouter {
return handlerCache;
}

send405(req, res, next) {
var err = new Error('Route defined in OpenAPI specification (' + req.openapi.openApiRoute + ') but there is no defined on' + req.method.toUpperCase() + ' operation.');
res.statusCode = 405;
return next(err);
}

initialize(options) {
var handlerCache = {};

Expand Down Expand Up @@ -97,14 +83,25 @@ export class SwaggerRouter {
handlerCache = this.handlerCacheFromDir(options.controllers);
}

const getHandlerName = this.getHandlerName;
const send405 = this.send405;
const getHandlerName = (req) => {
if (req.openapi.schema['x-swagger-router-controller']) {
return req.openapi.schema['x-swagger-router-controller'] + '_' + (req.openapi.schema.operationId ? req.openapi.schema.operationId : req.method.toLowerCase());
} else {
return req.openapi.schema.operationId;
}
};

const send405 = (req, res, next) => {
let err = new Error('Route defined in OpenAPI specification (' + req.openapi.openApiRoute + ') but there is no defined on' + req.method.toUpperCase() + ' operation.');
res.statusCode = 405;
return next(err);
};

return function swaggerRouter (req, res, next) {
var operation = req.openapi ? req.openapi.schema.operationId : undefined;
var handler;
var handlerName;
var rErr;
return (req, res, next) => {
let operation = req.openapi ? req.openapi.schema.operationId : undefined;
let handler;
let handlerName;
let rErr;

debug('%s %s', req.method, req.url);
debug(' Will process: %s', isUndefined(operation) ? 'no' : 'yes');
Expand All @@ -123,27 +120,22 @@ export class SwaggerRouter {

if (!isUndefined(handler)) {
try {
return handler(req, res, next);
return handler.apply(this, req.openapi.swaggerParameters);
} catch (err) {
rErr = err;

debug('Handler threw an unexpected error: %s\n%s', err.message, err.stack);
}
} else if (options.ignoreMissingHandlers !== true) {
rErr = new Error('Cannot resolve the configured swagger-router handler: ' + handlerName);

res.statusCode = 500;
}
} else {
debug(' No handler for method: %s', req.method);

return send405(req, res, next);
}

if (rErr) {
debugError(rErr, debug);
}

return next(rErr);
};
};
Expand Down

0 comments on commit 206d593

Please sign in to comment.