Comparing version 1.3.0 to 2.0.0
65
index.js
@@ -6,3 +6,2 @@ const methods = ['get', 'delete', 'patch', 'post', 'put', 'head', 'options'] | ||
} | ||
const URL = require('url') | ||
const reqHandler = require('./libs/middleware-chain') | ||
@@ -13,7 +12,14 @@ | ||
server.on('request', (req, res) => { | ||
app.handler(req, res) | ||
setImmediate(() => app.handler(req, res)) | ||
}) | ||
const wayfarer = require('wayfarer')('/404') | ||
wayfarer.on('/404', () => 404) | ||
const router = require('find-my-way')({ | ||
ignoreTrailingSlash: options.ignoreTrailingSlash || false, | ||
allowUnsafeRegex: options.allowUnsafeRegex || false, | ||
maxParamLength: options.maxParamLength || 100, | ||
defaultRoute: (req, res) => { | ||
res.send(404) | ||
} | ||
}) | ||
const routes = {} | ||
@@ -38,9 +44,15 @@ const middlewares = [] | ||
} | ||
wayfarer.on(key, (params, req, res) => { | ||
router.on(method, path, (req, res, params) => { | ||
try { | ||
req.params = params | ||
const result = routes[key].handler.call(ctx, req, res, ctx) | ||
let {handler, ctx} = routes[key] | ||
const result = handler.call(ctx, req, res, ctx) | ||
if (result instanceof Promise) { | ||
// async support | ||
result.catch(res.send) | ||
result.then(data => { | ||
if (undefined !== data) { | ||
return res.send(data) | ||
} | ||
}).catch(res.send) | ||
} | ||
@@ -59,25 +71,20 @@ } catch (err) { | ||
handler: (req, res) => { | ||
for (const method of Object.keys(exts.response)) { | ||
res[method] = exts.response[method](req, res) | ||
} | ||
const url = URL.parse(req.url) | ||
req.path = url.path | ||
req.query = url.query | ||
req.search = url.search | ||
res.send = exts.response.send(req, res) | ||
// calling middlewares | ||
reqHandler([ | ||
...middlewares.slice(0), | ||
{ | ||
context: {}, | ||
handler: (req, res, next) => { | ||
const route = `[${req.method.toUpperCase()}]${req.path}` | ||
if (wayfarer(route, req, res) === 404) res.send(404) | ||
if (middlewares.length) { | ||
reqHandler([ | ||
...middlewares.slice(0), | ||
{ | ||
context: {}, | ||
handler: (req, res, next) => { | ||
router.lookup(req, res) | ||
} | ||
} | ||
} | ||
], | ||
req, | ||
res | ||
)() | ||
], | ||
req, | ||
res | ||
)() | ||
} else { | ||
router.lookup(req, res) | ||
} | ||
}, | ||
@@ -102,3 +109,3 @@ start: (port = 3000, host) => | ||
methods.forEach((method) => { | ||
app[method] = (path, handler, ctx) => app.route(method, path, handler, ctx) | ||
app[method] = (path, handler, ctx) => app.route(method.toUpperCase(), path, handler, ctx) | ||
}) | ||
@@ -105,0 +112,0 @@ |
@@ -24,3 +24,3 @@ const next = (middlewares, req, res) => { | ||
} else if (!res.finished) { | ||
res.end() | ||
res.send(res.statusCode) | ||
} | ||
@@ -27,0 +27,0 @@ } |
@@ -13,2 +13,3 @@ module.exports.send = (req, res) => (data = 200, code = 200, headers = {}) => { | ||
data = { | ||
errClass: data.constructor.name, | ||
code, | ||
@@ -18,13 +19,8 @@ message: data.message, | ||
} | ||
} | ||
if (typeof data === 'number') { | ||
} else if (typeof data === 'number') { | ||
code = parseInt(data, 10) | ||
data = res.body | ||
} | ||
if (typeof data === 'object') { | ||
res.setHeader('content-type', 'application/json') | ||
data = JSON.stringify(data) | ||
} | ||
// emit response event before send and terminate | ||
// emit response event | ||
const params = { | ||
@@ -38,2 +34,7 @@ res, | ||
if (typeof data === 'object') { | ||
res.setHeader('content-type', 'application/json') | ||
params.data = JSON.stringify(params.data) | ||
} | ||
res.writeHead(params.code) | ||
@@ -40,0 +41,0 @@ res.end(params.data, 'utf-8', (err) => { |
{ | ||
"name": "restana", | ||
"version": "1.3.0", | ||
"version": "2.0.0", | ||
"description": "Super fast and minimalist web framework for building REST micro-services.", | ||
@@ -36,3 +36,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"wayfarer": "^6.6.4" | ||
"find-my-way": "^1.13.0" | ||
}, | ||
@@ -42,2 +42,5 @@ "devDependencies": { | ||
"express": "^4.16.3", | ||
"fastify": "^1.5.0", | ||
"koa": "^2.5.1", | ||
"koa-router": "^7.4.0", | ||
"mocha": "^5.2.0", | ||
@@ -44,0 +47,0 @@ "morgan": "^1.9.0", |
# REST-Ana | ||
Super fast and minimalist web framework for building REST micro-services. | ||
Super fast and minimalist *connect-like* web framework for building REST micro-services. | ||
> Uses 'find-my-way' blazing fast router: https://www.npmjs.com/package/find-my-way | ||
@@ -28,2 +29,15 @@ ## Usage | ||
### Configuration | ||
- `server`: Allows to override the HTTP server instance to be used. | ||
- `ignoreTrailingSlash`: If `TRUE`, trailing slashes on routes are ignored. Default value: `FALSE` | ||
- `allowUnsafeRegex`: If `TRUE`, potentially catastrophic exponential-time regular expressions are disabled. Default value: `FALSE` | ||
- `maxParamLength`: Dfines the custom length for parameters in parametric (standard, regex and multi) routes. | ||
#### Example usage: | ||
```js | ||
const service = require('restana')({ | ||
ignoreTrailingSlash: true | ||
}); | ||
``` | ||
### Creating the micro-service interface | ||
@@ -71,2 +85,3 @@ ```js | ||
``` | ||
### Stopping the service | ||
@@ -76,2 +91,13 @@ ```js | ||
``` | ||
### Async / Await support | ||
```js | ||
// some fake "star" handler | ||
service.post('/star/:username', async (req, res) => { | ||
const stars = await starService.star(req.params.username) | ||
return stars | ||
}); | ||
``` | ||
> IMPORTANT: Returned value can't be `undefined`, for such cases use `res.send(...` | ||
### Middleware usage: | ||
@@ -85,4 +111,4 @@ ```js | ||
res.on('response', data => { | ||
data.res.setHeader('X-Response-Time', new Date().getTime() - now); | ||
res.on('response', e => { | ||
e.res.setHeader('X-Response-Time', new Date().getTime() - now); | ||
}); | ||
@@ -101,2 +127,20 @@ | ||
``` | ||
#### Catching exceptions | ||
```js | ||
service.use((req, res, next) => { | ||
res.on('response', e => { | ||
if (e.code >= 400) { | ||
if (e.data && e.data.errClass) { | ||
console.log(e.data.errClass + ': ' + e.data.message) | ||
} else { | ||
console.log('error response, but not triggered by an Error instance') | ||
} | ||
} | ||
}) | ||
return next(); | ||
}); | ||
``` | ||
### Sending custom headers: | ||
@@ -110,3 +154,3 @@ ```js | ||
Third party middlewares support: | ||
> Almost all middlewares using the *function (req, res, next)* signature format should work. With the consideration that they don't use any custom framework feature. | ||
> Almost all middlewares using the *function (req, res, next)* signature format should work, considering that no custom framework feature is used. | ||
@@ -119,11 +163,13 @@ Examples : | ||
## Performance comparison | ||
Performance comparison for a basic *Hello World!* response in cluster mode with 4 processes: | ||
Performance comparison for a basic *Hello World!* response (single thread process). | ||
Node version: v10.4.0 | ||
Laptop: MacBook Pro 2016, 2,7 GHz Intel Core i7, 16 GB 2133 MHz LPDDR3 | ||
```bash | ||
ab -n 10000 -c 1000 http://localhost:3000/v1/welcome | ||
wrk -t8 -c8 -d30s http://localhost:3000/hi | ||
``` | ||
Results: | ||
* restana: ~1300ms | ||
* koa: ~1500ms | ||
* hapi: ~4200ms | ||
* express: ~1800ms | ||
* restify: ~2000ms | ||
* fastify: Requests/sec: 36894.86 | ||
* **restana**: Requests/sec 29899.10 | ||
* koa: Requests/sec 23486.64 | ||
* express: Requests/sec 16057.22 | ||
* ... comparison N/A |
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
11268
165
168
10
+ Addedfind-my-way@^1.13.0
+ Addedfast-decode-uri-component@1.0.1(transitive)
+ Addedfind-my-way@1.18.1(transitive)
+ Addedret@0.1.15(transitive)
+ Addedsafe-regex@1.1.0(transitive)
+ Addedsemver-store@0.3.0(transitive)
- Removedwayfarer@^6.6.4
- Removedwayfarer@6.6.4(transitive)
- Removedxtend@4.0.2(transitive)