Skip to content

Instantly share code, notes, and snippets.

@FND
Last active July 25, 2022 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FND/ca8cf55e66dd6da126c1ee10ce60a6ab to your computer and use it in GitHub Desktop.
Save FND/ca8cf55e66dd6da126c1ee10ce60a6ab to your computer and use it in GitHub Desktop.
simplistic router with web standards
import { Router } from "./router.js";
let router = new Router([
["/blog/:article", makeHandler("BLOG")],
["/blog/:article/:comment", makeHandler("COMMENT")],
["/api/*", makeHandler("API")]
]);
let uris = [
"/foo",
"/blog",
"/blog/",
"/blog/abc123",
"/blog/abc123/comments",
"/api/search?q=lorem+ipsum;sort=asc",
"/api/search?q=lorem%20ipsum&sort=asc",
"/api/comments/:username"
];
for(let uri of uris) {
try {
router.dispatch(`http://localhost${uri}`);
} catch(err) {
console.error("ERROR:", err.message);
}
}
function makeHandler(name) {
return (...args) => console.log(`[${name}]`, ...args);
}
export class Router {
constructor(routes) {
this.routes = new Map();
for(let [pattern, handler] of routes) {
this.register(pattern, handler);
}
}
dispatch(uri) {
for(let [pattern, handler] of this.routes) {
let res = pattern.exec(uri);
if(!res) {
continue;
}
let { pathname, search } = res;
handler(uri, {
params: pathname.groups,
query: new Map([...new URLSearchParams(search.groups[0])])
});
return;
}
throw new Error(`no matching route for \`${uri}\``);
}
register(pattern, handler) {
if(pattern.substr) {
pattern = { pathname: pattern };
}
let _pattern = new URLPattern(pattern);
this.routes.set(_pattern, handler);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment