Router

Router

Simple Trie (Prefix Tree) router uses a trie data structure to store routes and handlers.

Middleware

A handler is a function (context, next) or an object with method handle(context, next).

When matched the handler can process the request and send back results or skip and pass the control to the next middleware by calling the next function.

When parameter or wildcard captured the context.params will be an object with captured values, named parameter will be a property with the same name but wildcards will be captured as array-like indexed values starting with '0'.

Routing Basics

The router matches an incoming request (e.g., GET /posts/123) against a set of registered routes defined using router.add(method, path_pattern, handler_data) or any shortcuts like get, post, put, patch, delete.

The router executes matches in the order routes are added. When multiple registered paths can satisfy an incoming request, all matching results are returned in the sequence they were added to the Router instance.

Method parameter may contain explicit order ID in the form #ID where ID is a number, it will be used in sorting instead of auto generated sequence id.

Examples

Request Path Route Registered Matching Criteria Notes
/users/123 (GET) /users/:username Matches the literal structure, capturing username. Parameter handling.
/api/posts/123 (GET) /api/:type/* Wildcard matches the path structure (/api/../...), captures the :path parameter. Wildcard usage.
router.get("/users/:user", middleware1);
router.get("/book/:slug", "middleware2)
router.get("/api/:type/*", middleware3);

router.find("get", "/users/123")
[{ route: { .. handler: middleware1 }, params: { user: "123" }}]

router.find("get", "/book/999")
[{ route: { .. handler: middleware2 }, params: { slug: "999" }}]

router.find("get", "/api/endpoint/123")
[{ route: { .. handler: middleware3 }, params: { '0': "123", 'type': "endpoint" }}]


Path Parameters (:param_name)

Parameters allow parts of a URL to be dynamic variables. The router captures these segments into a params object on the matching route.

Example:

router.get("/entry/:id/comment/:comment_id", (context, next) => { ... });

const res = router.find('get', '/entry/789/comment/123');

// Result will contain a match where params are { id: '789', comment_id: '123' }

Wildcards (*)

The wildcard character (*) is used to catch any path segment. It can be placed anywhere in the route definition but the segment must exist even if the '*' is at the end.

Pattern Match Type Effect Example Matches
/api/* Two-level Wildcard Matches the segment immediately after /api/... but not just /api /api/posts, /api/users/a
* Catch All Matches any request path, acting as a fallback or middleware layer if defined early in the router setup. /any/path, /

Example:

router.get("/entry/:id/*", (context, next) => { ... });

const res = router.find('get', '/entry/789/123');

// Result will contain a match where params are { id: '789', '0': '123' }

Constructor

new Router(handleropt)

Description:
  • Create a new router with default fallback handler

Source:
Parameters:
Name Type Attributes Description
handler function <optional>

Methods

add(method, path, handler)

Description:
  • Inserts a path into the Trie.

Source:
Parameters:
Name Type Description
method string

to handle, optional sorting ID can be set as #ID

path string

to handle

handler any

associated data

Example
router.add("GET", "/api/info", middleware1)
router.add("*", "/api/", middleware2)

all(path)

Description:
  • Add a route to all methods

Source:
Parameters:
Name Type Description
path string
...handlers function()
Example
router.all("/api/info", middleware1)

del(method, path, handleropt) → {Array.<object>}

Description:
  • Delete a handler from the Trie, must match explicitly by method, path with optional handler

Source:
Parameters:
Name Type Attributes Description
method string

to handle

path string

to handle

handler any <optional>

associated data, if missing all handlers will be deleted

Returns:
Type Description
Array.<object>
  • deleted routes
Example
router.del("GET", "/api/info", middleware1)
router.del("*", "/api/")

delete(path)

Description:
  • Add DELETE route

Source:
Parameters:
Name Type Description
path string
...handlers function()

find(path) → {Array.<object>}

Description:
  • Retrieves all nodes that match a path.

Source:
Parameters:
Name Type Description
path string

to check.

Returns:
Type Description
Array.<object>

matched routes { route, params }, ...

get(path, handler)

Description:
  • Add GET route

Source:
Parameters:
Name Type Description
path string
handler function()
Example
router.get("/api/get", middleware1)

handle(context, next)

Description:
  • Handle a request

Source:
Parameters:
Name Type Description
context RequestContext
next function()

(context, err) called after all routes processed but none returned response or error, can be chained to next middleware

onFinish()

Description:
  • Default handler to call if no routes matched or error detected

Source:

patch(path, handler)

Description:
  • Add PATCH route

Source:
Parameters:
Name Type Description
path string
handler function()

post(path, handler)

Description:
  • Add POST route

Source:
Parameters:
Name Type Description
path string
handler function()
Example
router.post("/api/update", middleware1)

put(path)

Description:
  • Add PUT route

Source:
Parameters:
Name Type Description
path string
...handlers function()

reset()

Description:
  • Clear and reset

Source:

split()

Description:
  • Split the path by separator, if empty return separator for explicit root match

Source:

use(methodopt, pathopt)

Description:
  • Add a route or midleware handlers

Source:
Parameters:
Name Type Attributes Default Description
method string <optional>
''

empty for all, or a valid HTTP method. Optional sorting ID can be appended as #ID, it will be used as is instead of default sequential id. This is to allow manual sorting of routes and not depend on order of definition.

path string <optional>
*
..handlers function() | object

middleware handlers, if an object it must have method .handle(context, next)

Example
router.use(middleware1, middleware2)
router.use("GET", "/api", midleware1)
router.use("/api", midleware1)

// This will be the first route even if added last
router.use("GET#0", /api", midleware5)

walk(callback)

Description:
  • Walk the trie non-recursively, call the callback for each leaf node

Source:
Parameters:
Name Type Description
callback function()