Define and manage application routes with CanxJS's powerful, intuitive API. Built on a Radix Tree for ultra-fast route matching with support for parameters, wildcards, and route groups.
Ultra-fast route matching with O(k) complexity where k is the path length
Capture dynamic values from URLs with :paramName syntax
Match multiple path segments with *wildcard syntax
Organize routes with prefixes and shared middleware
Define routes using HTTP method helpers like app.get(),app.post(),app.put(), andapp.delete(). Each method takes a path and a handler function.
1import { createApp } from "canxjs";23const app = createApp({ port: 3000 });45// GET request6app.get("/", (req, res) => {7return res.json({ message: "Hello CanxJS!" });8});910// POST request11app.post("/users", async (req, res) => {12const userData = await req.body();13return res.status(201).json({ created: userData });14});1516// PUT request17app.put("/users/:id", async (req, res) => {18const { id } = req.params;19const userData = await req.body();20return res.json({ updated: { id, ...userData } });21});2223// DELETE request24app.delete("/users/:id", (req, res) => {25const { id } = req.params;26return res.json({ deleted: id });27});2829app.listen();
Capture dynamic values from URLs using colon syntax (:paramName). Parameters are available in req.params, while query strings are in req.query.
1// Single parameter2app.get("/users/:id", (req, res) => {3const { id } = req.params;4return res.json({ userId: id });5});67// Multiple parameters8app.get("/posts/:postId/comments/:commentId", (req, res) => {9const { postId, commentId } = req.params;10return res.json({ postId, commentId });11});1213// Optional query parameters14app.get("/search", (req, res) => {15const { q, page, limit } = req.query;16return res.json({17query: q,18page: page || 1,19limit: limit || 1020});21});
Use wildcards (*) to match any path segment. You can also name wildcards to capture the matched path. Useapp.all() to match all HTTP methods.
1// Wildcard route - catches all paths after /files/2app.get("/files/*path", (req, res) => {3const filePath = req.params.path;4return res.json({5message: "File requested",6path: filePath7});8});910// Catch-all 404 handler11app.all("*", (req, res) => {12return res.status(404).json({13error: "Not Found",14path: req.path15});16});
Organize routes with common prefixes using app.group(). Groups can be nested to create hierarchical route structures.
1// Group routes with a common prefix2app.group("/api/v1", (router) => {3router.get("/users", getUsers);4router.get("/users/:id", getUser);5router.post("/users", createUser);6router.put("/users/:id", updateUser);7router.delete("/users/:id", deleteUser);8});910// Nested groups11app.group("/admin", (admin) => {12admin.group("/users", (users) => {13users.get("/", listAdminUsers);14users.post("/", createAdminUser);15});1617admin.group("/settings", (settings) => {18settings.get("/", getSettings);19settings.put("/", updateSettings);20});21});
Give your routes a name for easier referencing. Use the name() method chain and the global route() helper to generate URLs.
1// Define named route2app.get("/users/:id", (req, res) => {3// ...4}).name("users.show");56// In your controller or view:7const url = route("users.show", { id: 123 });8// Output: /users/123910// Redirect using named route11return res.redirect(route("users.show", { id: 1 }));
Apply middleware to specific routes or route groups. Middleware is executed in order before the route handler.
1import { createApp, cors, logger } from "canxjs";23const app = createApp({ port: 3000 });45// Auth middleware6const authMiddleware = async (req, res, next) => {7const token = req.header("authorization");89if (!token) {10return res.status(401).json({ error: "Unauthorized" });11}1213req.context.set("user", { id: 1, name: "John" });14return next();15};1617// Apply middleware to specific route18app.get("/profile", authMiddleware, (req, res) => {19const user = req.context.get("user");20return res.json({ profile: user });21});2223// Apply middleware to route group24app.group("/api", (router) => {25router.middleware(authMiddleware);26router.get("/dashboard", getDashboard);27router.get("/settings", getSettings);28});
New in v1.6.3: Use router.controller() to register entire controller classes with their decorated routes. This provides cleaner, more organized routing similar to Laravel.
1import { createApp, QueueController } from "canxjs";2import { HomeController } from "./controllers/HomeController";3import { AuthController } from "./controllers/AuthController";45// New in v1.6.3: Controller-based routing6app.routes((router) => {7// Mount controllers with router.controller()8router.controller('/', HomeController);9router.controller('/auth', AuthController);1011// Built-in Queue Dashboard12router.controller('/canx-queue', QueueController);13});
| Option | Type | Default | Description |
|---|---|---|---|
| caseSensitive | boolean | false | Treat /Users and /users as different routes |
| trailingSlash | 'ignore' | 'require' | 'remove' | 'ignore' | How to handle trailing slashes |
| cache | boolean | true | Enable route matching cache |
1import { createRouter, createApp } from "canxjs";23// Create router with options4const router = createRouter({5caseSensitive: true, // /Users ≠ /users6trailingSlash: "remove", // /users/ → /users7cache: true // Enable route caching8});910// Use the router11router.get("/users", getUsers);12router.post("/users", createUser);1314// Mount router15const app = createApp({ port: 3000 });16// Routes from router are registered with app