Skip to main content

Routing

Signature

All routes in CrumbJS follow the same signature:

// Route signature
app[method](path, handler, options?);

app.get("/path", handler, routeConfig);
app.post("/path", handler, routeConfig);
app.put("/path", handler, routeConfig);
app.patch("/path", handler, routeConfig);
app.delete("/path", handler, routeConfig);
app.options("/path", handler, routeConfig);
app.head("/path", handler, routeConfig);

// Special routes (explained later)
app.proxy(method, localPath, dest, routeConfig);
app.proxyAll(localPath, dest, use);
app.static(path, content, type)

Wildcards and params

// Basic param usage (inferred as string)
app.get("/user/:id", ({ params }) => {
return `User id is: ${params.id}`; // is type-safe too without defining schema
});

// Defining validation rules for the path params
app.get("/user/:id", ({ params }) => {
return `User id is: ${params.id}`;
}, {
params: z.object({ // must be a Zod Object
id: z.string().min(36), // must define rules to all index without ':'
})
});

// Some advanced things you can do with Path Params + Zod + Drizzle
app.get(
"/user/:user/posts",
async ({ params }) => {
return params.user.name; // return user name from "db"
},
{
// If `params` is defined, you must describe ALL path params
params: z.object({
user: z.string().transform(async (val) => {
const user = await db.query.users.findFirst({
where: eq(users.id, val)
});
if (!user) throw new NotFound();
return user;
}),
}),
}
);

// Wildcard (match everything after /user/)
app.get("/user/*", ({ params }) => {
return `Matched path: ${params["*"]}`;
});

Handlers

A route handler in CrumbJS receives a single argument: the Context object.
Context is a rich object that contains everything you need to work with the request and response.
We will dive deeper into Context in the next section.

The return value of a handler must be one of the following:

  • an object (automatically serialized to JSON),
  • null, or
  • a Response instance.
app.get("/path-to-route", async (ctx) => {
return { message: "Hello World" }; // object, null, or Response
});