Code Monkey home page Code Monkey logo

ana's Introduction

restana

Build Status NPM version Greenkeeper badge Blazing fast, tiny 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

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: Dfines the custom length for parameters in parametric (standard, regex and multi) routes.

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 = { // optionally you can send the response data in the body property
        version: '1.0.0'
    };
    res.send(); // 200 is the default response code
});

Supported HTTP methods:

const methods = ['get', 'delete', 'put', 'patch', 'post', 'head', 'options'];

Starting the service

service.start(3000).then((server) => {});

Stopping the service

service.close().then(()=> {});

Async / Await support

// some fake "star" handler
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(...

Sending custom headers:

res.send('Hello World', 200, {
    'x-response-time': 100
});

Acknowledge from low-level end operation

res.send('Hello World', 200, {}, (err) => {
    if (err) {
        // upppsss
    }
});

Middleware usage:

const service = require('restana')({});

// custom middleware to attach the X-Response-Time header to the response
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();
});

// the /v1/welcome route handler
service.get('/v1/welcome', (req, res) => {
    res.send('Hello World!');
});

// start the server
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 ๐Ÿš€

// required dependencies
const serverless = require('serverless-http');
const restana = require('restana');

// creating service
const service = restana();
service.get('/hello', (req, res) => {
    res.send('Hello World!');
});

// lambda integration
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!');
});

// using "the callback integrator" middleware
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
// ATTENTION: The performance of the service below can blow your mind ;)
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)

Performance comparison for a basic Hello World! response (single thread process).
Node version: v10.11.0
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 57622.13
  • restana: Requests/sec 43575.36
  • restana-cluster: Requests/sec 71626.33
  • fastify: Requests/sec 36894.86
  • koa: Requests/sec 23486.64
  • restify: Requests/sec 21903.95
  • hapi: Requests/sec 16509.12
  • express: Requests/sec 16057.22

JSON response ({msg: 'Hello World!'})

  • restana-turbo-http: Requests/sec 53025.65
  • restana: Requests/sec 39681.39
  • fastify: Requests/sec 33143.12
  • restify: Requests/sec 24631.74
  • koa: Requests/sec 22485.43
  • hapi: Requests/sec 15921.77
  • express: Requests/sec 14569.78

Polka micro-framework is not considered because it misses JSON response auto-detection.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.