Route Patterns
Reference: Fast Router GitHub Repository
Deserve uses Fast Router (radix tree) for route matching and parameter extraction. File paths in the routes folder are turned into patterns; dynamic segments use [param], which becomes :param at the router level.
Pattern Matching
Deserve converts file paths to route patterns. FastRouter handles pattern matching with radix tree for optimal performance:
.
├── routes/index.ts → /
├── routes/about.ts → /about
├── routes/users/[id].ts → /users/:id
├── routes/users/[id]/posts.ts → /users/:id/postsDynamic Parameters
Use [param] syntax for dynamic route segments:
Single Parameter
typescript
// File: routes/users/[id].ts
// 1. Import Context
import type { Context } from '@neabyte/deserve'
// 2. GET /users/:id — get param from ctx.param('id')
export function GET(ctx: Context): Response {
const id = ctx.param('id')
return ctx.send.json({ userId: id })
}Multiple Parameters
typescript
// File: routes/users/[id]/posts/[postId].ts
// 1. One ctx.param per dynamic segment
import type { Context } from '@neabyte/deserve'
export function GET(ctx: Context): Response {
const id = ctx.param('id')
const postId = ctx.param('postId')
return ctx.send.json({ userId: id, postId })
}Nested Parameters
typescript
// File: routes/api/v1/users/[userId]/posts/[postId]/comments/[commentId].ts
// 1. Each [param] in path → ctx.param('param')
import type { Context } from '@neabyte/deserve'
export function GET(ctx: Context): Response {
const userId = ctx.param('userId')
const postId = ctx.param('postId')
const commentId = ctx.param('commentId')
return ctx.send.json({ userId, postId, commentId })
}Pattern Examples
User Management
routes/
├── users.ts → /users
├── users/[id].ts → /users/:id
├── users/[id]/profile.ts → /users/:id/profile
├── users/[id]/posts.ts → /users/:id/posts
└── users/[id]/posts/[postId].ts → /users/:id/posts/:postIdAPI Versioning
routes/
├── api/
│ ├── v1/
│ │ └── users/[id].ts → /api/v1/users/:id
│ └── v2/
│ └── users/[id].ts → /api/v2/users/:idBlog System
routes/
├── blog/
│ ├── [slug].ts → /blog/:slug
│ └── [year]/
│ └── [month]/
│ └── [day]/
│ └── [slug].ts → /blog/:year/:month/:day/:slugParameter Validation
Extract and validate parameters in your route handlers:
typescript
// File: routes/users/[id].ts
// 1. Get param then validate; if invalid → 400
import type { Context } from '@neabyte/deserve'
// GET /users/:id
export function GET(ctx: Context): Response {
const id = ctx.param('id')
if (!id || !/^\d+$/.test(id)) {
return ctx.send.json({ error: 'Invalid user ID' }, { status: 400 })
}
return ctx.send.json({ userId: parseInt(id) })
}