jkyberneees / low-http-server

HTTP Server implementation in top of uWebSocket.js
MIT License
50 stars 7 forks source link

low-http-server

Build Status NPM version
HTTP server implementation for Node.js based on uWebSockets.js!

Formerly part of the 0http project!

Introduction

low-http-server is a Node.js wrapper around the great uWebSockets.js library. Here, I/O throughput is maximized at the cost of API compatibility, when we compare it to the standard Node.js HTTP server interface.

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

const server = require('low-http-server')({})
server.on('request', (req, res) => {
  res.end('Hello World!')
})

server.listen(3000, () => {
  console.log('Server listening on http://0.0.0.0:3000')
})

Or with SSL:

const server = require('low-http-server')({
  cert_file_name: './demos/test.crt',
  key_file_name: './demos/test.key',
  passphrase: 'test'
})

server.on('request', (req, res) => {
  res.end('Hello World!')
})

server.listen(3000, () => {
  console.log('Server listening on http://0.0.0.0:3000')
})

Benchmarks

Machine: MacBook Pro (13-inch, 2020), 1,4 GHz Quad-Core Intel Core i5
Node.js version: 12.18.3

wrk -t8 -c40 -d5s http://127.0.0.1:3000

Take note that low-http-server does not clusterize on anything besides reasonably recent versions of Linux kernel. You may deploy several instances listening on different IPs and being proxied (e.g. by nginx) as a workaround.

Clusterization could be possibly implemented, as soon as uWebSockets.js gets support for listening to a socket.

Known limitations

Integrations

General notes

Low-http-server has become more compatible with Node.js standard interface, but it is not perfect. Despite certain quirks, low-http-server can often replace the usual node http module backend and serve as an underlying server for popular node.js frameworks. There are only two known requirements:

0http framework

const low = require('low-http-server')
const cero = require('0http')

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

router.get('/hi', (req, res) => {
  res.end('Hello World!')
})

server.listen(3000, (socket) => {
  if (socket) {
    console.log('HTTP server ready!')
  }
})

restana framework

No problems, if prioRequestsProcessing is set to false.

const server = require('low-http-server')({})

const service = require('restana')({
  server: server,
  prioRequestsProcessing: false // NOTE: required for restana integration
})

server.listen(3000, () => {
  console.log('Server listening on http://0.0.0.0:3000')
})

service.get('/', (req,res) => {
  res.send('It works!')
})

Fastify

Other frameworks

Please refer to their documentation on how to use your own server.