Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lukeed/trouter
:fish: A fast, small-but-mighty, familiar fish...errr, router*
https://github.com/lukeed/trouter
Last synced: 6 days ago
JSON representation
:fish: A fast, small-but-mighty, familiar fish...errr, router*
- Host: GitHub
- URL: https://github.com/lukeed/trouter
- Owner: lukeed
- License: mit
- Created: 2017-11-05T19:35:11.000Z (almost 7 years ago)
- Default Branch: main
- Last Pushed: 2024-06-02T16:21:11.000Z (5 months ago)
- Last Synced: 2024-10-25T19:09:27.052Z (9 days ago)
- Language: JavaScript
- Homepage:
- Size: 70.3 KB
- Stars: 642
- Watchers: 7
- Forks: 23
- Open Issues: 2
-
Metadata Files:
- Readme: readme.md
- Funding: .github/FUNDING.yml
- License: license
Awesome Lists containing this project
- awesome - trouter - :fish: A fast, small-but-mighty, familiar fish...errr, router* (JavaScript)
- awesome-list - trouter - but-mighty, familiar fish...errr, router* | lukeed | 499 | (JavaScript)
README
# trouter [![CI](https://github.com/lukeed/trouter/actions/workflows/ci.yml/badge.svg)](https://github.com/lukeed/trouter/actions/workflows/ci.yml)
> 🐟 A fast, small-but-mighty, familiar ~fish~ router
## Install
```
$ npm install --save trouter
```## Usage
```js
import { Trouter } from 'trouter';const router = new Trouter();
// Define all routes
router
.get('/users', _ => {
console.log('> Getting all users');
})
.add('POST', '/users', _ => {
console.log('~> Adding a user');
})
.get('/users/:id', val => {
console.log('~> Getting user with ID:', val);
});// Find a route definition
let obj = router.find('GET', '/users/123');
//=> obj.params ~> { id:123 }
//=> obj.handlers ~> Array// Execute the handlers, passing value
obj.handlers.forEach(fn => {
fn(obj.params.id);
});
//=> ~> Getting user with ID: 123// Returns empty keys when no match
router.find('DELETE', '/foo');
//=> { params:{}, handlers:[] }
```## API
### Trouter()
Initializes a new `Trouter` instance.### trouter.add(method, pattern, ...handlers)
Returns: `self`Stores a `method` + `pattern` pairing internally, along with its handler(s).
#### method
Type: `String`Any uppercased, [valid HTTP/1.1 verb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods#Specifications) — choose from one of the following:
```
GET HEAD PATCH OPTIONS CONNECT DELETE TRACE POST PUT
```#### pattern
Type: `String` or `RegExp`Trouter supports simple route patterns which are fast and well readable but limited. If you need more complex patterns, you can pass an instance of `RegExp` with parameters specified as named capture groups.
> **Important:** RegExp named capture groups are [supported in Node.js 10.x](https://node.green/#ES2018-features--RegExp-named-capture-groups) and above!
The supported route pattern types are:
* static (`/users`)
* named parameters (`/users/:id`)
* nested parameters (`/users/:id/books/:title`)
* optional parameters (`/users/:id?/books/:title?`)
* suffixed parameters (`/movies/:title.mp4`, `movies/:title.(mp4|mov)`)
* any match / wildcards (`/users/*`)
* optional wildcards (`/users/*?`)#### ...handlers
Type: `Function`The function(s) that should be tied to this `pattern`.
Because this is a [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters), whatever you pass will _always_ be cast to an Array.
> **Important:** Trouter does not care what your function signature looks like!
You are not bound to the `(req, res)` standard, or even passing a `Function` at all!### trouter.use(pattern, ...handlers)
Returns: `self`This is an alias for [`trouter.add('', pattern, ...handlers)`](#trouteraddmethod-pattern-handlers), matching **all** HTTP methods.
However, unlike [`trouter.all`](#trouterallpattern-handlers), the `pattern` you defined **IS NOT RESTRICTIVE**, which means that the route will match any & all URLs that start (but not end) with a matching segment.
```js
router.use('/foo', 'USE /foo');
router.use('/foo/:name', 'USE /foo/:name');
router.post('/foo/:name', 'POST /foo/:name');
router.head('/foo/:name/hello', 'HEAD /foo/:name/hello');router.find('GET', '/foo').handlers;
//=> ['USE /foo']router.find('POST', '/foo/bar').handlers;
//=> ['USE /foo', 'USE /foo/:name', 'POST /foo/:name']router.find('HEAD', '/foo/bar/hello').handlers;
//=> ['USE /foo', 'USE /foo/:name', 'HEAD /foo/:name/hello']
```
_Compare this snippet with the one below to see differences between `trouter.all` and this method._### trouter.all(pattern, ...handlers)
Returns: `self`This is an alias for [`trouter.add('', pattern, ...handlers)`](#trouteraddmethod-pattern-handlers), matching **all** HTTP methods.
However, unlike [`trouter.use`](#trouterusepattern-handlers), the `pattern` you defined **IS RESTRICTIVE** and behaves like any other [`trouter.METHOD`](#trouteraddmethod-pattern-handlers) route. This means that the URL must match the defined `pattern` exactly – or have the appropriate optional and/or wildcard segments to accommodate the desired flexibility.
```js
router.all('/foo', 'ALL /foo');
router.all('/foo/:name', 'ALL /foo/:name');
router.post('/foo/:name', 'POST /foo/:name');
router.head('/foo/:name/hello', 'HEAD /foo/:name/hello');router.find('GET', '/foo').handlers;
//=> ['ALL /foo']router.find('POST', '/foo/bar').handlers;
//=> ['ALL /foo/:name', 'POST /foo/:name']router.find('HEAD', '/foo/bar/hello').handlers;
//=> ['HEAD /foo/:name/hello']
```
_Compare this snippet with the one above to see differences between `trouter.use` and this method._### trouter.METHOD(pattern, ...handlers)
This is an alias for [`trouter.add(METHOD, pattern, ...handlers)`](#trouteraddmethod-pattern-handlers), where `METHOD` is any lowercased HTTP verb.
```js
const noop = _ => {}:
const app = new Trouter();app.get('/users/:id', noop);
app.post('/users', noop);
app.patch('/users/:id', noop);// less common methods too
app.trace('/foo', noop);
app.connect('/bar', noop);
```### trouter.find(method, url)
Returns: `Object`Searches within current instance for **all** `method` + `pattern` pairs that satisfy the current `method` + `url`.
> **Important:** Parameters and handlers are assembled/gathered _in the order that they were defined!_
This method will always return an Object with `params` and `handlers` keys.
* `params` — Object whose keys are the named parameters of your route pattern.
* `handlers` — Array containing the `...handlers` provided to [`.add()`](#trouteraddmethod-pattern-handlers) or [`.METHOD()`](#troutermethodpattern-handlers)> **Note:** The `handlers` and `params` keys will be empty if no matches were found.
#### method
Type: `String`Any valid HTTP method name, uppercased.
> **Note:** When searching for `HEAD` routes, `GET` routes will also be inspected.
#### url
Type: `String`The URL used to match against pattern definitions. This is typically `req.url`.
## Benchmarks
> Run on Node v10.13.0
```
GET / x 10,349,863 ops/sec ±2.15% (93 runs sampled)
POST /users x 13,895,099 ops/sec ±0.40% (94 runs sampled)
GET /users/:id x 6,288,457 ops/sec ±0.25% (93 runs sampled)
PUT /users/:id/books/:title? x 6,176,501 ops/sec ±0.22% (96 runs sampled)
DELETE /users/:id/books/:title x 5,581,288 ops/sec ±2.04% (96 runs sampled)
HEAD /hello (all) x 9,700,097 ops/sec ±0.47% (90 runs sampled)
```## License
MIT © [Luke Edwards](https://lukeed.com)