Yet another faster Node.js micro framework: 0http

Introduction

In this article we introduce a Node.js micro framework called 0http (https://www.npmjs.com/package/0http), or just “cero”.

I built cero over restana development learnings and it’s focused on HTTP I/O throughput over APIs abstractions or enterprise aspects support. Being more specific, cero is a minimalist HTTP framework that was developed to show how fast the Node.js runtime can be, so this is the library that beats benchmarks 😉

PROS: Extreme high I/O throughput.
CONS: Vanilla HTTP interfaces, no magic methods.

https://github.com/jkyberneees/0http#benchmarks-22072019

Hello World HTTP server using cero

const cero = require('0http')
const { router, server } = cero()
 
router.on('GET', '/hello/:name', (req, res, params) => {
  res.end('Hello World: ' + params.name)
})

server.listen(3000)

Pluggable servers and routers

With cero you can use the HTTP server and routes you like.

Routers

Router implementations are required to support the following interface:

router.lookup = (req, res) => {
  // -> routes matching
  // -> handler(s) execution
}

find-my-way router

https://github.com/delvedor/find-my-way

This is the default router if no router is provided via configuration. Internally uses a Radix Tree router that will bring better performance over iterative regular expressions matching.

0http – sequential

Custom implementation of the trouter router for cero. Includes support for middlewares and shortcuts for routes registration.
As this is an iterative regular expression matching router, it tends to be slower than find-my-way when the number of registered routes increases. However, tiny micro-services should not see major performance degradation.

Supported HTTP verbs: GET, HEAD, PATCH, OPTIONS, CONNECT, DELETE, TRACE, POST, PUT

const cero = require('0http')
const { router, server } = cero({
  router: require('0http/lib/router/sequential')()
})

router.use('/', (req, res, next) => {
  res.write('Hello ')
  next()
})

const routeMiddleware = (req, res, next) => {
  res.write('World')
  next()
}
router.get('/sayhi', routeMiddleware, (req, res) => {
  res.end('!')
})

server.listen(3000)

Async middlewares

You can user async middlewares to await the remaining chain execution:

router.use('/', async (req, res, next) => {
  try {
    await next()
  } catch (err) {
    res.statusCode = 500
    res.end(err.message)
  }
})

router.get('/sayhi', () => { 
  throw new Error('Uuuups!') 
}, (req, res) => {
  res.end('!')
})

Servers

const cero = require('0http')

const { router, server } = cero({
  server: yourCustomServerInstance
})

Node.js http.Server

If no server is provided by configuration, the standard Node.js http.Server implementation is used.
Because this server offers the best balance between Node.js ecosystem compatibility and performance, we highly recommend it for most use cases.

Low Server

low is a tiny Node.js friendly wrapper around the great uWebSockets.js HTTP server. I/O throughput is maximized at the cost of API compatibility.

As far as for Node.js, uWebSockets.js brings the best I/O performance in terms of HTTP support.

Using low server: https://github.com/jkyberneees/0http#low-server

Conclusions

Cero is a low level, extremely fast micro framework for Node.js that you can use to build high performance HTTP services.

Due to the lack of high level abstractions, cero is recommended for advanced developers who are familiar with vanilla HTTP interfaces in Node.js.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.