Comparing version 3.2.3 to 3.3.0
95
index.js
@@ -60,4 +60,2 @@ /** | ||
const routes = {} | ||
// global middlewares holder | ||
const middlewares = [] | ||
// routes registration shortcut factory | ||
@@ -71,2 +69,8 @@ const addRoute = (methods) => (path, ...args) => { | ||
// global middlewares holder | ||
const middlewares = [{ | ||
handler: (req, res, next) => router.lookup(req, res), | ||
context: {} | ||
}] | ||
// error handler | ||
@@ -97,6 +101,7 @@ const errorHandler = options.errorHandler || ((err, req, res) => res.send(err)) | ||
use: (middleware, context = {}) => { | ||
middlewares.push({ | ||
handler: middleware, | ||
context | ||
}) | ||
middlewares.splice( | ||
middlewares.length - 1, | ||
0, | ||
{ handler: middleware, context } | ||
) | ||
}, | ||
@@ -125,41 +130,35 @@ | ||
const key = `[${method.toString().toUpperCase()}]${path}` | ||
if (!routes[key]) { | ||
// caching route arguments | ||
routes[key] = { | ||
method, | ||
path, | ||
handler, | ||
ctx, | ||
middlewares | ||
} | ||
// caching route arguments | ||
routes[key] = { | ||
method, | ||
path, | ||
handler, | ||
ctx, | ||
middlewares | ||
} | ||
// registering request handler | ||
router.on(method, path, (req, res, params) => { | ||
// populate req.params | ||
req.params = params | ||
// destructing arguments | ||
const { handler, ctx, middlewares } = routes[key] | ||
// Allow override of routes, by first removing the old route | ||
router.off(method, path) | ||
if (middlewares.length > 0) { | ||
// call route middlewares and route handler | ||
next([ | ||
...middlewares.slice(0), | ||
{ | ||
context: {}, | ||
handler: handlerCall(handler, ctx, errorHandler) // -> Function | ||
} | ||
], req, res, errorHandler)() | ||
} else { | ||
// directly call the route handler only | ||
// NOTE: we do this to increase performance | ||
handlerCall(handler, ctx, errorHandler)(req, res) | ||
} | ||
}) | ||
} else { | ||
// update route parameters if route exist | ||
routes[key].ctx = ctx | ||
routes[key].handler = handler | ||
routes[key].middlewares = middlewares | ||
} | ||
// registering request handler | ||
router.on(method, path, (req, res, params) => { | ||
// populate req.params | ||
req.params = params | ||
if (middlewares.length > 0) { | ||
// call route middlewares and route handler | ||
return next([ | ||
...middlewares.slice(0), | ||
{ | ||
context: {}, | ||
handler: handlerCall(handler, ctx, errorHandler) // -> Function | ||
} | ||
], req, res, errorHandler) | ||
} else { | ||
// directly call the route handler only | ||
// NOTE: we do this to increase performance | ||
return handlerCall(handler, ctx, errorHandler)(req, res) | ||
} | ||
}) | ||
return routes[key] | ||
@@ -179,13 +178,5 @@ }, | ||
if (middlewares.length > 0) { | ||
if (middlewares.length > 1) { | ||
// call route middlewares and route handler | ||
next([ | ||
...middlewares.slice(0), | ||
{ | ||
context: {}, | ||
handler: (req, res, next) => { | ||
router.lookup(req, res) | ||
} | ||
} | ||
], req, res, errorHandler)() | ||
next(middlewares, req, res, errorHandler) | ||
} else { | ||
@@ -192,0 +183,0 @@ // directly call the request router |
@@ -9,7 +9,7 @@ /** | ||
*/ | ||
const next = (middlewares, req, res, errorHandler) => { | ||
function next (middlewares, req, res, errorHandler, middlewareIndex = 0) { | ||
// retrieve next middleware from chain | ||
const middleware = middlewares.shift() | ||
const middleware = middlewares[middlewareIndex] | ||
return (err) => { | ||
function step (err) { | ||
if (err) return errorHandler(err, req, res) | ||
@@ -19,12 +19,3 @@ if (res.statusCode === 200 && !res.finished) { | ||
try { | ||
// invoke each middleware | ||
const result = middleware.handler.call(middleware.context, req, res, next(middlewares, req, res, errorHandler)) | ||
if (result instanceof Promise) { | ||
// async support | ||
result.catch(err => errorHandler(err, req, res)) | ||
} | ||
} catch (err) { | ||
errorHandler(err, req, res) | ||
} | ||
return next(middlewares, req, res, errorHandler, ++middlewareIndex) | ||
} else if (!res.finished) { | ||
@@ -34,4 +25,10 @@ res.send(res.statusCode) | ||
} | ||
try { | ||
return middleware.handler.call(middleware.context, req, res, step) | ||
} catch (e) { | ||
errorHandler(e, req, res) | ||
} | ||
} | ||
module.exports = next |
{ | ||
"name": "restana", | ||
"version": "3.2.3", | ||
"version": "3.3.0", | ||
"description": "Super fast and minimalist web framework for building REST micro-services.", | ||
@@ -49,5 +49,4 @@ "main": "index.js", | ||
"fastify": "^1.14.6", | ||
"finalhandler": "^1.1.2", | ||
"hapi": "^17.8.4", | ||
"http-cache-middleware": "^1.2.1", | ||
"http-cache-middleware": "^1.2.3", | ||
"koa": "^2.7.0", | ||
@@ -54,0 +53,0 @@ "koa-router": "^7.4.0", |
@@ -143,17 +143,4 @@ # restana | ||
### Route Level Middlewares | ||
Connecting middlewares to specific routes is also supported: | ||
```js | ||
service.get('/hi/:name', async (req, res) => { | ||
return 'Hello ' + req.params.name // -> "name" will be uppercase here | ||
}, {}, [(req, res, next) => { | ||
req.params.name = req.params.name.toUpperCase() | ||
next() | ||
}]) // route middlewares can be passed in an Array after the handler context param | ||
``` | ||
Express.js like signature also supported: | ||
```js | ||
service.get('/hi/:name', m1, m2, handler [, ctx]) | ||
``` | ||
### Sending custom headers: | ||
@@ -188,3 +175,3 @@ ```js | ||
### Middleware usage: | ||
### Middlewares support: | ||
```js | ||
@@ -212,2 +199,17 @@ const service = require('restana')({}) | ||
### Route level middlewares | ||
Connecting middlewares to specific routes is also supported: | ||
```js | ||
service.get('/hi/:name', async (req, res) => { | ||
return 'Hello ' + req.params.name // -> "name" will be uppercase here | ||
}, {}, [(req, res, next) => { | ||
req.params.name = req.params.name.toUpperCase() | ||
next() | ||
}]) // route middlewares can be passed in an Array after the handler context param | ||
``` | ||
Express.js like signature also supported: | ||
```js | ||
service.get('/hi/:name', m1, m2, handler [, ctx]) | ||
``` | ||
#### Third party middlewares support: | ||
@@ -222,2 +224,28 @@ > Almost all middlewares using the *function (req, res, next)* signature format should work, considering that no custom framework feature is used. | ||
#### Async middlewares support | ||
Starting from `v3.3.x`, you can now also use async middlewares as described below: | ||
```js | ||
service.use(async (req, res, next) => { | ||
await next() | ||
console.log('Global middlewares execution completed!') | ||
})) | ||
service.use(logging()) | ||
service.use(jwt()) | ||
``` | ||
In the same way you can also capture uncaught exceptions inside your async middlewares: | ||
```js | ||
service.use(async (req, res, next) => { | ||
try { | ||
await next() | ||
} catch (err) { | ||
console.log('upps, something just happened') | ||
res.send(err) | ||
} | ||
}) | ||
service.use(logging()) | ||
service.use(jwt()) | ||
``` | ||
> NOTE: Global and Route level middlewares execution run separately! | ||
## AWS Serverless Integration | ||
@@ -224,0 +252,0 @@ `restana` is compatible with the [serverless-http](https://github.com/dougmoscrop/serverless-http) library, so restana based services can also run as AWS lambdas 🚀 |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27053
22
293
508