From a0bc5516971d4fb81adc0e48500dc60c8c734ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20=C5=BDaromskis?= Date: Sat, 27 Jan 2018 16:26:33 +0200 Subject: [PATCH 1/4] Allow async handlers --- .jshintrc | 2 +- README.md | 10 ++++++++++ lib/expressroutes.js | 33 ++++++++++++++++++++++++++------- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/.jshintrc b/.jshintrc index 9776863..08f61c0 100644 --- a/.jshintrc +++ b/.jshintrc @@ -49,7 +49,7 @@ "lastsemic": false, "iterator": false, "funcscope": false, - "esnext": false, + "esnext": true, "newcap": false, "noempty": false, diff --git a/README.md b/README.md index 2a679a9..ace19fb 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,16 @@ module.exports = { } ``` +### Async Handlders +async/await requires at least node 7.6. Errors that occurred in async function will be automatically passed to next() callback +```javascript +module.exports = { + get: async (req, res) => { ... }, + put: async (req, res) => { ... }, + ... +} +``` + ### Handler Middleware Handlers can also specify middleware chains by providing an array of handler functions under the verb: diff --git a/lib/expressroutes.js b/lib/expressroutes.js index a24ee68..3e6250e 100644 --- a/lib/expressroutes.js +++ b/lib/expressroutes.js @@ -6,6 +6,19 @@ var async = require('async'), utils = require('swaggerize-routes/lib/utils'), pathRegexp = require('path-to-regexp'); +/** + * Wraps try catch block around async function + * Errors are sent to next handler automatically + * + * @param fn + * @return {Function} + */ +function asyncMiddleware(fn) { + return function (req, res, next) { + Promise.resolve(fn(req, res, next)) + .catch(next); + }; +} /** * Makes default accessor functions for a specific data location, e.g. query, params etc @@ -125,26 +138,32 @@ function buildRoutePath(mountpath, path) { * @param routeSpec */ function makeExpressRoute(router, mountpath, route, securityDefinitions) { - var path, args, before, validators; + var path, args, before, validators, handlers, i; path = buildRoutePath(mountpath, route.path); args = [path]; before = []; + handlers = []; if (route.security) { before.push(authorizeFor(route.security, securityDefinitions)); } - if (thing.isArray(route.handler)) { - if (route.handler.length > 1) { - Array.prototype.push.apply(before, route.handler.slice(0, route.handler.length - 1)); + if (!thing.isArray(route.handler)) { + route.handler = [route.handler]; + } + + for (i = 0; i < route.handler.length; ++i) { + if (route.handler[i].constructor.name === "AsyncFunction") { + handlers.push(asyncMiddleware(route.handler[i])); + } else { + handlers.push(route.handler[i]); } - route.handler = route.handler[route.handler.length - 1]; } validators = []; - for (var i = 0; i < route.validators.length; ++i) { + for (i = 0; i < route.validators.length; ++i) { validators.push(makeValidator(route.validators[i], route.consumes)); } @@ -152,7 +171,7 @@ function makeExpressRoute(router, mountpath, route, securityDefinitions) { Array.prototype.push.apply(args, before); - args.push(route.handler); + Array.prototype.push.apply(args, handlers); router[route.method].apply(router, args); } From dd9e5f61e56cf0e51403ae0be2e998f13cb40822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20=C5=BDaromskis?= Date: Tue, 27 Feb 2018 11:29:11 +0200 Subject: [PATCH 2/4] Fix a warning about not returned Promise --- lib/expressroutes.js | 3 +-- package.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/expressroutes.js b/lib/expressroutes.js index 3e6250e..0f804ac 100644 --- a/lib/expressroutes.js +++ b/lib/expressroutes.js @@ -15,8 +15,7 @@ var async = require('async'), */ function asyncMiddleware(fn) { return function (req, res, next) { - Promise.resolve(fn(req, res, next)) - .catch(next); + return Promise.resolve(fn(req, res, next)).catch(next); }; } diff --git a/package.json b/package.json index 293e5b0..00f919c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "swaggerize-express", - "version": "4.0.6", + "version": "4.0.7", "author": "Trevor Livingston ", "contributors": [ "Trevor Livingston ", From 6e6147f0e1392257818c02320bb52b24ea2f2f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20=C5=BDaromskis?= Date: Thu, 8 Mar 2018 17:28:57 +0200 Subject: [PATCH 3/4] Prove that async handlers do work --- package.json | 2 +- test/fixtures/handlers/pets/{id}.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 00f919c..240b7d4 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ }, "bugs": "http://github.com/krakenjs/swaggerize-express/issues", "engines": { - "node": "<=4.x" + "node": ">=4.8.7" }, "dependencies": { "async": "^1.5.0", diff --git a/test/fixtures/handlers/pets/{id}.js b/test/fixtures/handlers/pets/{id}.js index a54c30f..7ffb216 100644 --- a/test/fixtures/handlers/pets/{id}.js +++ b/test/fixtures/handlers/pets/{id}.js @@ -4,7 +4,10 @@ var store = require('../../lib/store'); module.exports = { - get: function (req, res) { + get: async (req, res) => { + // pretend waiting for database + await new Promise(res => setTimeout(res, 10)); + res.json(store.get(req.params['id'])); }, delete: function (req, res) { From 5b5021d507d5b5ce03bbb352047d2389cb8adba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20=C5=BDaromskis?= Date: Thu, 8 Mar 2018 17:31:47 +0200 Subject: [PATCH 4/4] Async await is a feature of node v8 --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 73d47bf..1c802ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,5 @@ language: node_js node_js: - - "0.12" - - "4" - - "6" - "8" branches: only: