Deno nuggets: Print all Oak routes
This article is a part of the Deno nuggets series, where each article attempts to suggest a pointed solution to a specific question that can be read in less than a minute. There is no ordering of nuggets.
Problem
How to print all Oak routes in complex applications for debugging purposes?
Solution
In real-world, applications are usually complex, with tens or hundreds of routes configured by different modules. In such cases, it’s hard to keep track of all the routes provided by the application. There may be tens of ES modules configuring their own routes in the main application router.
Consider the following application with two simple modules (a, and b):
// -- app.tsimport { Application, Router } from "https://deno.land/x/oak/mod.ts";
import { configure as A } from "./a.ts";
import { configure as B } from "./b.ts";const app = new Application();
const router = new Router();
router
.get("/", (ctx) => {})
.get("/a", (ctx) => {})
.put("/a/:id", (ctx) => {})
.delete("/a/:id", (ctx) => {});A(router);
B(router);app.use(router.routes());
app.use(router.allowedMethods());app.listen({ hostname: "127.0.0.1", port: 8000 });// -- a.tsexport function configure(router) {
router
.get("/x/y", (ctx) => {})
.post("/x/y/:msgId", (ctx) => {})
.put("/x/y/", (ctx) => {})
.delete("/x/y/:msgId", (ctx) => {});
}// -- b.tsexport function configure(router) {
router
.get("/i/j/k/l", (ctx) => {})
.post("/i/j/k/l/:assetId", (ctx) => {});
}
This is still manageable. Now imagine the same application running into hundreds of routes from tens of modules.
To print all the supported routes for debugging, documentation, etc. we can use Oak’s router iterable interface. This can be done by simply adding the following lines after the router is fully configured:
for (const r of router) {
console.log(r);
}
This’ll print all the configured routes in Oak’s internal format:
> deno run --allow-net app.ts
{
methods: [ "HEAD", "GET" ],
middleware: [ [Function] ],
paramNames: [],
path: "/",
regexp: /^\/[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "HEAD", "GET" ],
middleware: [ [Function] ],
paramNames: [],
path: "/a",
regexp: /^\/a[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "PUT" ],
middleware: [ [Function] ],
paramNames: [ "id" ],
path: "/a/:id",
regexp: /^\/a(?:\/([^\/#\?]+?))[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "DELETE" ],
middleware: [ [Function] ],
paramNames: [ "id" ],
path: "/a/:id",
regexp: /^\/a(?:\/([^\/#\?]+?))[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "HEAD", "GET" ],
middleware: [ [Function] ],
paramNames: [],
path: "/x/y",
regexp: /^\/x\/y[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "POST" ],
middleware: [ [Function] ],
paramNames: [ "msgId" ],
path: "/x/y/:msgId",
regexp: /^\/x\/y(?:\/([^\/#\?]+?))[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "PUT" ],
middleware: [ [Function] ],
paramNames: [],
path: "/x/y/",
regexp: /^\/x\/y\/[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "DELETE" ],
middleware: [ [Function] ],
paramNames: [ "msgId" ],
path: "/x/y/:msgId",
regexp: /^\/x\/y(?:\/([^\/#\?]+?))[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "HEAD", "GET" ],
middleware: [ [Function] ],
paramNames: [],
path: "/i/j/k/l",
regexp: /^\/i\/j\/k\/l[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}
{
methods: [ "POST" ],
middleware: [ [Function] ],
paramNames: [ "assetId" ],
path: "/i/j/k/l/:assetId",
regexp: /^\/i\/j\/k\/l(?:\/([^\/#\?]+?))[\/#\?]?$/i,
options: {
end: undefined,
sensitive: undefined,
strict: undefined,
ignoreCaptures: undefined
}
}