- 3.0.0-beta.7Latest
- 3.0.0-beta.6
- 3.0.0-beta.5
- 3.0.0-beta.4
- 3.0.0-beta.3
- 3.0.0-beta.2
- 3.0.0-beta.1
- 2.1.0
- 2.1.0-beta.3
- 2.1.0-beta.2
- 2.1.0-beta.1
- 1.0.0-beta.6
- 2.0.0
- 2.0.0-beta.3
- 2.0.0-beta.2
- 2.0.0-beta.1
- 1.2.0
- 1.2.0-beta.5
- 1.2.0-beta.4
- 1.2.0-beta.3
- 1.2.0-beta.2
- 1.2.0-beta.1
- 1.1.0
- 1.1.0-beta.1
- 1.0.0
- 1.0.0-beta.5
- 1.0.0-beta.4
- 1.0.0-beta.3
- 1.0.0-beta.2
- 1.0.0-beta.1
http-router
HTTP request router for standard Request
and Response
.
- Based on URL pattern API
- Web standard API compliant
- Declarative interface
- Functional programing pattern matching style
- Automatically
HEAD
request handler - Nested route pathname
- Tiny, lean
Packages
The package supports multiple platforms.
- deno.land/x -
https://deno.land/x/http_router/mod.ts
- npm -
@httpland/http-router
HTTP request url router
URLRouter
provides routing between HTTP request URLs and handlers.
Request URL are matched with the URLPatten API
.
import { URLRouter } from "https://deno.land/x/http_router@$VERSION/mod.ts";
import { serve } from "https://deno.land/std@$VERSION/http/mod.ts";
const handler = URLRouter({
"/api/students/:name": (request, context) => {
const greeting = `Hello! ${context.params.name!}`;
return new Response(greeting);
},
"/api/status": () => new Response("OK"),
});
await serve(handler);
URL Route handler context
The URL route handler receives the following context.
Name | Description |
---|---|
params | { readonly [k in string]?: string } URL matched parameters. |
route | string Route pathname. |
pattern | URLPattern URL pattern. |
URL match pattern
URL patterns can be defined using the URL pattern API.
- Literal strings which will be matched exactly.
- Wildcards (
/posts/*
) that match any character. - Named groups (
/books/:id
) which extract a part of the matched URL. - Non-capturing groups (
/books{/old}?
) which make parts of a pattern optional or be matched multiple times. - RegExp groups (
/books/(\\d+)
) which make arbitrarily complex regex matches with a few limitations.
Nested route pathname
nest
is nested URL pathname convertor. It provides a hierarchy of routing
tables.
Hierarchical definitions are converted to flat definitions.
You can define a tree structure with a depth of 1. To nest more, combine it.
Example of a routing table matching the following URL:
- /
- /api/v1/users
- /api/v1/products
- /api/v2/users
- /api/v2/products
import {
nest,
URLRouter,
} from "https://deno.land/x/http_router@$VERSION/mod.ts";
const routeHandler = () => new Response();
const v2 = nest("v2", {
users: routeHandler,
products: routeHandler,
});
const api = nest("/api", {
...nest("v1", {
users: routeHandler,
products: routeHandler,
}),
...v2,
});
const handler = URLRouter({ ...api, "/": routeHandler });
Joining path segment
Path segments are joined without overlapping slashes.
import { nest } from "https://deno.land/x/http_router@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std@$VERSION/testing/asserts.ts";
const routeHandler = () => new Response();
assertEquals(
nest("api/", {
"/hello": routeHandler,
}),
{
"api/hello": routeHandler,
},
);
HTTP request method router
MethodRouter
provides routing between HTTP request methods and handlers.
import { MethodRouter } from "https://deno.land/x/http_router@$VERSION/mod.ts";
import { serve } from "https://deno.land/std@$VERSION/http/mod.ts";
const handler = MethodRouter({
GET: () => new Response("From GET"),
POST: async (request) => {
const data = await request.json();
return new Response("Received data!");
},
});
await serve(handler);
HEAD request handler
By default, if a GET
request handler is defined, a HEAD
request handler is
automatically added.
This feature is based on RFC 9110, 9.1
All general-purpose servers MUST support the methods GET and HEAD.
import { MethodRouter } from "https://deno.land/x/http_router@$VERSION/mod.ts";
import { serve } from "https://deno.land/std@$VERSION/http/mod.ts";
import { assertEquals } from "https://deno.land/std@$VERSION/testing/asserts.ts";
const handler = MethodRouter({
GET: () => {
const body = `Hello! world`;
return new Response(body, {
headers: {
"content-length": new Blob([body]).size.toString(),
},
});
},
});
const request = new Request("http://localhost", { method: "HEAD" });
const response = await handler(request);
assertEquals(response.body, null);
assertEquals(response.headers.get("content-length"), "12");
This can be disabled by setting withHead
to false
.
import { MethodRouter } from "https://deno.land/x/http_router@$VERSION/mod.ts";
const handler = MethodRouter({}, { withHead: false });
Error handling policy
The router is a closure. It is designed to create handlers via initialization.
During the initialization step, routes are examined, actively looking for errors and throwing errors.
This ensures that the routes you define are semantically correct.
Here are the conditions under which errors are thrown:
- Duplicate pattern
- Empty routes
These are all semantic errors that cannot be eliminated by type checking alone.
On the other hand, the handler created is guaranteed not to throw errors.
If your defined handler throws an error internally, it will be supplemented and
safely return a Response
.
Here is the default response on error.
HTTP/1.1 500 Internal Server Error
Detect error
onError
is called when an error is thrown internally by the handler. You may
customize the error response.
import { URLRouter } from "https://deno.land/x/http_router@$VERSION/mod.ts";
const handler = URLRouter({
"/": () => {
throw Error("oops");
},
}, {
onError: (error) => {
console.error(error);
return new Response("Something wrong :(", {
status: 500,
});
},
});
Spec
In addition to user-defined responses, routers may return the following responses:
Status | Headers | Condition |
---|---|---|
404 | URLRouter If not all url pattern match. |
|
405 | allow |
MethodRouter If HTTP method handler is not defined. |
500 | URLRouter , MethodRouter If an internal error occurs. |
API
All APIs can be found in the deno doc.
Performance
version 1.2 or later
Caches URL matching results internally. This speeds up the response time for
requests that have already been matched by ^20X
.
Benchmark
Benchmark script with comparison to several popular routers is available.
deno task bench
Benchmark results can be found here.
Recipes
http-router can be used with any module.
License
Copyright © 2022-present httpland.
Released under the MIT license