Groups & API Versioning
Route groups allow you to apply shared configuration—such as prefixes, guards, and middleware—to a logical set of routes. This significantly reduces boilerplate and enforces consistency across your API.
Basic Groups
Use router.group() to define a set of routes that share a common URL prefix.
typescript
router.group({ prefix: "/users" }, (group) => {
group.get("/", (req, res) => res.success("User list"));
group.post("/", (req, res) => res.success("User created"));
group.get("/:id", (req, res) => res.success(`User ${req.params.id}`));
});
// Resulting paths: GET /users/, POST /users/, GET /users/:idNested Groups
Groups can be arbitrarily nested to produce complex hierarchical APIs with overlapping shared logic.
typescript
router.group({ prefix: "/api" }, (api) => {
api.group({ prefix: "/v1" }, (v1) => {
v1.get("/status", (req, res) => res.success("V1 OK"));
});
api.group({ prefix: "/v2" }, (v2) => {
v2.get("/status", (req, res) => res.success("V2 OK"));
v2.get("/users", (req, res) =>
res.json({ users: [], meta: { page: 1 } }),
);
});
});
// Resulting paths: /api/v1/status, /api/v2/status, /api/v2/usersAPI Versioning
XyPriss provides a semantic shorthand for versioned APIs, ensuring consistency and readability.
Using router.version()
typescript
router.version("v1", (r) => {
r.get("/users", (req, res) => res.success("V1 Users"));
});
router.version("v2", (r) => {
r.get("/users", (req, res) => res.success("V2 Users"));
});
// Paths: /v1/users, /v2/usersPath Order
When both
prefix and version are provided in a group config, the version is always prepended to the prefix:/{version}/{prefix}.Group Guards & Security
Security guards applied at the group level are automatically inherited by every route within that group. This is the recommended approach for protecting entire API namespaces.
typescript
const adminGuard = (req: any, _res: any) => {
if (req.user?.role === "admin") return true;
return "Admin access required";
};
router.group(
{
prefix: "/admin",
guards: [adminGuard],
},
(admin) => {
admin.get("/dashboard", (req, res) => res.success("Admin dashboard"));
admin.get("/users", (req, res) => res.json({ users: [] }));
// adminGuard runs before BOTH routes
},
);Parameters & Constraints
Learn how to handle dynamic parameters, regex constraints, and query parsing.
