restana
Blazing fast, tiny and minimalist connect-like web framework for building REST micro-services.
Uses 'find-my-way' router: https://www.npmjs.com/package/find-my-way
What else? Building ultra-fast REST APIs with Node.js (restana vs express vs fastify)
Usage
npm i restana --save
Creating the service instance
Create unsecure HTTP server:
const service = require('restana')();
Passing HTTP server instance:
const https = require('https');
const service = require('restana')({
server: https.createServer({
key: keys.serviceKey,
cert: keys.certificate
})
});
See examples:
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
: Defines the custom length for parameters in parametric (standard, regex and multi) routes. Default value: 100
defaultRoute
: Default route handler when no route match occurs. Default value: ((req, res) => res.send(404))
Example usage:
const service = require('restana')({
ignoreTrailingSlash: true
});
Creating the micro-service interface
const bodyParser = require('body-parser');
service.use(bodyParser.json());
const PetsModel = {
};
service.get('/pets/:id', async (req, res) => {
res.send(await PetsModel.findOne(req.params.id));
});
service.get('/pets', async (req, res) => {
res.send(await PetsModel.find());
});
service.delete('/pets/:id', async (req, res) => {
res.send(await PetsModel.destroy(req.params.id));
});
service.post('/pets/:name/:age', async (req, res) => {
res.send(await PetsModel.create(req.params));
});
service.patch('/pets/:id', async (req, res) => {
res.send(await PetsModel.update(req.params.id, req.body))
});
service.get('/version', function (req, res) {
res.body = {
version: '1.0.0'
};
res.send();
});
Supported HTTP methods:
const methods = ['get', 'delete', 'put', 'patch', 'post', 'head', 'options', 'trace'];
Starting the service
service.start(3000).then((server) => {});
Stopping the service
service.close().then(()=> {});
Async / Await support
service.post('/star/:username', async (req, res) => {
await starService.star(req.params.username);
const stars = await starService.count(req.params.username);
return stars;
});
IMPORTANT: Returned value can't be undefined
, for such cases use res.send(...
Route Level Middlewares
Connecting middlewares to specific routes is also supported:
service.get('/hi/:name', async (req, res) => {
return 'Hello ' + req.params.name
}, {}, [(req, res, next) => {
req.params.name = req.params.name.toUpperCase()
next()
}])
res.send('Hello World', 200, {
'x-response-time': 100
});
Acknowledge from low-level end
operation
res.send('Hello World', 200, {}, (err) => {
if (err) {
}
});
Middleware usage:
const service = require('restana')({});
service.use((req, res, next) => {
let now = new Date().getTime();
res.on('response', e => {
e.res.setHeader('X-Response-Time', new Date().getTime() - now);
});
return next();
});
service.get('/v1/welcome', (req, res) => {
res.send('Hello World!');
});
service.start();
Catching exceptions
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();
});
Third party middlewares support:
Almost all middlewares using the function (req, res, next) signature format should work, considering that no custom framework feature is used.
Examples :
AWS Serverless Integration
restana
is compatible with the serverless-http library, so restana based services can also run as AWS lambdas 🚀
const serverless = require('serverless-http');
const restana = require('restana');
const service = restana();
service.get('/hello', (req, res) => {
res.send('Hello World!');
});
const handler = serverless(app);
module.exports.handler = async (event, context) => {
return await handler(event, context);
};
Third party integrations
const service = restana()
service.get('/hello', (req, res) => {
res.send('Hello World!');
});
const server = http.createServer(service.callback());
turbo-http integration
What is turbo-http? Checkout: https://www.npmjs.com/package/turbo-http
Using turbo-http
in restana:
npm i turbo-http
const server = require('restana/libs/turbo-http');
const service = require('restana')({
server
});
service.get('/hi', (req, res) => {
res.send({
msg: 'Hello World!'
});
});
service.start();
NOTE: When using turbo-http
, the node.js cluster
module can't be used!
Performance comparison (framework overhead)
measurements below refers to version 2.3.0 (current version is faster)
Performance comparison for a basic Hello World! response (single thread process).
Node version: v10.14.1
Laptop: MacBook Pro 2016, 2,7 GHz Intel Core i7, 16 GB 2133 MHz LPDDR3
wrk -t8 -c8 -d30s http://localhost:3000/hi
String response ('Hello World!')
- restana-turbo-http: Requests/sec 57708.05
- restana: Requests/sec 46314.39
- restana-cluster: Requests/sec 70979.80
- fastify: Requests/sec 36873.05
- restify: Requests/sec 26388.94
- koa: Requests/sec 25686.12
- hapi: Requests/sec 20279.23
- express: Requests/sec 16812.15
JSON response ({msg: 'Hello World!'})
- restana-turbo-http: Requests/sec 53544.21
- restana: Requests/sec 39363.91
- fastify: Requests/sec 33600.85
- restify: Requests/sec 29490.79
- koa: Requests/sec 23787.82
- hapi: Requests/sec 19404.48
- express: Requests/sec 15365.56
Which is the fastest?
You can also checkout restana
performance index on the "Which is the fastest" project: https://github.com/the-benchmarker/web-frameworks#full-table-1