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

0http

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

0http - npm Package Compare versions

Comparing version 1.2.4 to 2.0.0

demos/basic-find-my-way-5-routes.js

2

demos/basic-sequential.js

@@ -8,3 +8,3 @@ const sequential = require('../lib/router/sequential')

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

@@ -11,0 +11,0 @@ })

const cero = require('./../index')
const { router, server } = cero()
router.on('GET', '/hi', (req, res) => {
router.get('/hi', (req, res) => {
res.end('Hello World!')

@@ -7,0 +6,0 @@ })

const http = require('http')
module.exports = (config = {}) => {
const router = config.router || require('find-my-way')()
const router = config.router || require('./lib/router/sequential')()
const server = config.server || http.createServer()

@@ -6,0 +6,0 @@

@@ -1,6 +0,6 @@

function next (middlewares, req, res, middlewareIndex = 0) {
const middleware = middlewares[middlewareIndex]
function next (middlewares, req, res, index, routerPatterns = {}, defaultRoute) {
const middleware = middlewares[index]
if (!middleware) {
if (!res.finished) {
return res.end()
return defaultRoute(req, res)
}

@@ -12,9 +12,19 @@

function step (err) {
if (err) return err
return next(middlewares, req, res, ++middlewareIndex)
if (err) throw err
return next(middlewares, req, res, ++index, routerPatterns, defaultRoute)
}
return middleware(req, res, step)
if (middleware.id) {
// nested routes support
const pattern = routerPatterns[middleware.id]
if (pattern) {
req.preRouterUrl = req.url
req.url = req.url.replace(pattern, '')
}
middleware.lookup(req, res, step)
} else {
return middleware(req, res, step)
}
}
module.exports = next
const Trouter = require('trouter')
const next = require('./../next')
const LRU = require('lru-cache')

@@ -9,14 +10,47 @@ module.exports = (config = {}) => {

})
config.cacheSize = config.cacheSize || 1000
config.id = config.id || (Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase()
const r = new Trouter()
let routersPattern = null
const cache = new LRU(config.cacheSize)
const router = new Trouter()
router.id = config.id
r.lookup = (req, res) => {
req.originalUrl = req.url
router.lookup = (req, res, step) => {
if (req.originalUrl === undefined) {
req.originalUrl = req.originalUrl || req.url
}
const match = r.find(req.method, req.url)
req.params = match.params
const reqCacheKey = `${req.method + req.url}`
let match = cache.get(reqCacheKey)
if (!match) {
match = router.find(req.method, req.url)
cache.set(reqCacheKey, match)
}
const middlewares = match.handlers.length
if (middlewares > 0) {
next(match.handlers, req, res)
if (match.handlers.length) {
if (routersPattern === null) {
routersPattern = {}
// caching router -> pattern relation for urls pattern replacement
router.routes.forEach(route => route.handlers.forEach(h => {
if (h.id) {
routersPattern[h.id] = route.pattern
}
}))
}
const middlewares = [...match.handlers]
if (step) {
// router is being used as a nested router
middlewares.push((req, res, next) => {
req.url = req.preRouterUrl
delete req.preRouterUrl
step()
})
}
// middlewares invocation
req.params = Object.assign(req.params || {}, match.params)
next(middlewares, req, res, 0, routersPattern, config.defaultRoute)
} else {

@@ -27,5 +61,5 @@ config.defaultRoute(req, res)

r.on = (method, pattern, ...handlers) => r.add(method, pattern, handlers)
router.on = (method, pattern, ...handlers) => router.add(method, pattern, handlers)
return r
return router
}

@@ -74,11 +74,7 @@ const uWS = require('uWebSockets.js')

this.req = uRequest
this.url = uRequest.getUrl()
this.originalUrl = this.url
this.method = uRequest.getMethod().toUpperCase()
this.body = null
this.headers = {}
this.headers = {}
uRequest.forEach((k, v) => {

@@ -85,0 +81,0 @@ this.headers[k] = v

{
"name": "0http",
"version": "1.2.4",
"version": "2.0.0",
"description": "Cero friction HTTP request router. The need for speed!",

@@ -9,3 +9,3 @@ "main": "index.js",

"format": "npx standard --fix",
"test": "PORT=3000 NODE_ENV=testing npx nyc --check-coverage --lines 85 node ./node_modules/mocha/bin/mocha tests.js"
"test": "PORT=3000 NODE_ENV=testing npx nyc --check-coverage --lines 85 node ./node_modules/mocha/bin/mocha tests/*.test.js"
},

@@ -30,4 +30,5 @@ "repository": {

"chai": "^4.2.0",
"mocha": "^6.2.0",
"nyc": "^14.1.1",
"find-my-way": "^2.2.1",
"mocha": "^6.2.2",
"nyc": "^15.0.0",
"standard": "^14.3.1",

@@ -38,5 +39,5 @@ "supertest": "^4.0.2",

"dependencies": {
"find-my-way": "^2.1.0",
"lru-cache": "^5.1.1",
"trouter": "^3.1.0"
}
}
# 0http
Cero friction HTTP framework:
- Tweaked Node.js Server for high throughput.
- The request router you like.
- Use the request router you like.
> If no router is provided, it uses the `find-my-way` router as default implementation.
## Usage

@@ -13,7 +11,7 @@ ```js

router.on('GET', '/hello', (req, res) => {
router.get('/hello', (req, res) => {
res.end('Hello World!')
})
router.on('POST', '/do', (req, res) => {
router.post('/do', (req, res) => {
// ...

@@ -34,12 +32,8 @@ res.statusCode = 201

```
### find-my-way router
> https://github.com/delvedor/find-my-way
This is the default router in `0http` if no router is provided via configuration. Internally uses a [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree)
router that will bring better performance over iterative regular expressions matching.
### 0http - sequential (default router)
This a `0http` extended implementation of the [trouter](https://www.npmjs.com/package/trouter) router. Includes support for middlewares, nested routers 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; to mitigate this issue, we use
an internal LRU cache to store the matching results of the previous requests, resulting on a super-fast matching process.
### 0http - sequential
This a `0http` extended implementation of the [trouter](https://www.npmjs.com/package/trouter) router. 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`

@@ -49,6 +43,5 @@

const cero = require('0http')
const { router, server } = cero({
router: require('0http/lib/router/sequential')()
})
const { router, server } = cero({})
// global middleware example
router.use('/', (req, res, next) => {

@@ -59,2 +52,3 @@ res.write('Hello ')

// route middleware example
const routeMiddleware = (req, res, next) => {

@@ -64,2 +58,4 @@ res.write('World')

}
// GET /sayhi route with middleware and handler
router.get('/sayhi', routeMiddleware, (req, res) => {

@@ -71,4 +67,14 @@ res.end('!')

```
#### Configuration Options
- **defaultRoute**: Route handler when there is no router matching. Default value:
```js
(req, res) => {
res.statusCode = 404
res.end()
}
```
- **cacheSize**: Router matching LRU cache size. Default value: `1000`
#### Async middlewares
You can user async middlewares to await the remaining chain execution:
You can user async middlewares to await the remaining chain execution. Let's describe with a custom error handler middleware:
```js

@@ -84,6 +90,41 @@ router.use('/', async (req, res, next) => {

router.get('/sayhi', () => { throw new Error('Uuuups!') }, (req, res) => {
res.end('!')
router.get('/sayhi', (req, res) => {
throw new Error('Uuuups!')
})
```
#### Nested Routers
You can simply use `sequential` router intances as nested routers:
```js
const cero = require('../index')
const { router, server } = cero({})
const nested = require('0http/lib/router/sequential')()
nested.get('/url', (req, res, next) => {
res.end(req.url)
})
router.use('/v1', nested)
server.listen(3000)
```
### find-my-way router
> https://github.com/delvedor/find-my-way
Super-fast raw HTTP router with no goodies. Internally uses a [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree)
router that will bring better performance over iterative regular expressions matching.
```js
const cero = require('../index')
const { router, server } = cero({
router: require('find-my-way')()
})
router.on('GET', '/hi', (req, res) => {
res.end('Hello World!')
})
server.listen(3000)
```
## Servers

@@ -121,3 +162,3 @@ `0http` is just a wrapper for the servers and routers implementations you provide.

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

@@ -137,31 +178,30 @@ })

## Benchmarks (22/07/2019)
**Node version**: v10.16.0
**Laptop**: MacBook Pro 2016, 2,7 GHz Intel Core i7, 16 GB 2133 MHz LPDDR3
## Benchmarks (30/12/2019)
**Node version**: v12.14.0
**Laptop**: MacBook Pro 2019, 2,4 GHz Intel Core i9, 32 GB 2400 MHz DDR4
**Server**: Single instance
```bash
wrk -t8 -c8 -d5s http://127.0.0.1:3000/hi
wrk -t8 -c40 -d5s http://127.0.0.1:3000/hi
```
### 1 route registered
- **0http (find-my-way + low)**
`Requests/sec: 121006.70`
- 0http (find-my-way)
`Requests/sec: 68101.15`
- 0http (sequential)
`Requests/sec: 67124.65`
- restana v3.3.1
`Requests/sec: 59519.98`
- **0http (find-my-way + low)**
`Requests/sec: 135436.99`
- 0http (sequential + low)
`Requests/sec: 134281.32`
- 0http (sequential)
`Requests/sec: 88438.69`
- 0http (find-my-way)
`Requests/sec: 87597.44`
- restana v3.4.2
`Requests/sec: 73455.97`
### 5 routes registered
- 0http (find-my-way)
`Requests/sec: 68067.34`
- 0http (sequential)
`Requests/sec: 64141.28`
- restana v3.3.1
`Requests/sec: 59501.34`
- **0http (sequential)**
`Requests/sec: 85839.17`
- 0http (find-my-way)
`Requests/sec: 82682.86`
> For more accurate benchmarks please see:
> - https://github.com/the-benchmarker/web-frameworks
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