Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

restana

Package Overview
Dependencies
Maintainers
1
Versions
97
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

restana

Super fast and minimalist web framework for building REST micro-services.

  • 3.4.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3.8K
decreased by-22.37%
Maintainers
1
Weekly downloads
 
Created
Source

restana

Build Status NPM version
Blazing fast, tiny and minimalist connect-like web framework for building REST micro-services.
> Check how much faster!

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.
  • routerFactory: Router factory function to allow default find-my-way router override.
  • prioRequestsProcessing: If TRUE, HTTP requests processing/handling is prioritized using setImmediate. Default value: TRUE
  • 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))
  • disableResponseEvent: If TRUE, there won't be response events triggered on the res object. Default value: FALSE
  • errorHandler: Optional global error handler function. Default value: (err, req, res) => res.send(err)
// accessing service configuration
service.getConfigOptions()
// accessing restana HTTP server instance
service.getServer()
Example usage:
const service = require('restana')({
  ignoreTrailingSlash: true
});
Optionally overwrite router factory method:

In this example we use anumargak router instead of find-my-way.

const anumargak = require('anumargak')
const service = require('restana')({
  routerFactory: (options) => {
    return anumargak(options)
  }
})
...

Please consider that when using anumargak router, request params are accessible via: req._path.params

Creating a micro-service & routes registration

const bodyParser = require('body-parser')

const service = require('restana')()
service.use(bodyParser.json())

const PetsModel = {
  // ... 
}

// registering routes using method chaining
service
  .get('/pets/:id', async (req, res) => {
    res.send(await PetsModel.findOne(req.params.id))
  })
  .get('/pets', async (req, res) => {
    res.send(await PetsModel.find())
  })
  .delete('/pets/:id', async (req, res) => {
    res.send(await PetsModel.destroy(req.params.id))
  })
  .post('/pets/:name/:age', async (req, res) => {
    res.send(await PetsModel.create(req.params))
  })
  .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', 'trace']
Using .all routes registration

You can also register a route handler for all supported HTTP methods:

service.all('/allmethodsroute', function (req, res) {
  res.send(200)
})
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
  }
})

Global error handling

const service = require('restana')({
  errorHandler (err, req, res) {
    console.log(`Something was wrong: ${err.message || err}`)
    res.send(err)
  }
})

service.get('/throw', (req, res) => {
  throw new Error('Upps!')
})

Middlewares support:

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

// custom middleware to attach the X-Response-Time header to the response
service.use((req, res, next) => {
  const 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()

Route level middlewares

Connecting middlewares to specific routes is also supported:

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:

service.get('/hi/:name', m1, m2, handler [, ctx])
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 :

Async middlewares support

Starting from v3.3.x, you can now also use async middlewares as described below:

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:

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

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)
}

Serving static files

You can read more about serving static files with restana in this link: https://thejs.blog/2019/07/12/restana-static-serving-the-frontend-with-node-js-beyond-nginx/

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())
//...

Application Performance Monitoring (APM)

As a Node.js framework implementation based on the standard http module, restana benefits from out of the box instrumentation on existing APM agents such as:

Elastic APM - Route Naming

"Routes Naming" discovery is not supported out of the box, but we have created our custom integration for Elastic APM:

// getting the Elastic APM agent
const apm = require('elastic-apm-node').start({
  secretToken: process.env.APM_SECRET_TOKEN,
  serverUrl: process.env.APM_SERVER_URL
})

// getting restana instrumentator 
const elasticApm = require('restana/libs/elastic-apm')
const { patch } = elasticApm({ apm })

// creating a restana application
const service = require('restana')()

// attach route naming instrumentation before registering service routes
patch(service)

// register your routes or middlewares
service.get('/hello', (req, res) => {
  res.send('Hello World!')
})

// ...

Performance comparison (framework overhead)

Which is the fastest?

You can checkout restana performance index on the "Which is the fastest" project: https://github.com/the-benchmarker/web-frameworks#full-table-1

Using this project? Let us know 🚀

https://goo.gl/forms/qlBwrf5raqfQwteH3

Breacking changes

3.x:

  • Support for turbo-http library was dropped.

Keywords

FAQs

Package last updated on 13 Dec 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc