Guides
Routing Requests
Use routers when path params and method filters are middleware concerns, not server adapter concerns.
Create a Router
Import routes from the router subpath. A router is callable middleware, so it
can be added to a chain with .use().
import { chain } from 'alien-middleware'
import { routes } from 'alien-middleware/router'
const router = routes()
router.use('/health', () => {
return new Response('ok')
})
const app = chain().use(router)
The route handler receives the same request context shape as middleware, plus route data when a path matches.
Read Path Parameters
Route paths use pathic path syntax. Parameters are inferred from the path
string.
const router = routes()
router.use('/users/:userId', context => {
return new Response(context.params.userId)
})
In this handler, context.params.userId is typed as string.
Filter by Method
Pass a method before the path to run a handler only for that method.
router.use('GET', '/items/:id', context => {
return new Response(`read ${context.params.id}`)
})
router.use('POST', '/items', () => {
return new Response('created', { status: 201 })
})
Use an array for multiple methods, or '*' for an explicit any-method route.
router.use(['PUT', 'PATCH'], '/items/:id', context => {
return new Response(`write ${context.params.id}`)
})
router.use('*', '/status', () => {
return new Response('up')
})
Routes with no method argument also match any method.
Share Middleware with Routes
Pass a middleware chain to routes() when all handlers in that router should
see the chain's context additions.
import { chain } from 'alien-middleware'
import { routes } from 'alien-middleware/router'
const auth = chain().use(() => {
return { user: { id: 'u_123', name: 'Ada' } }
})
const privateRoutes = routes(auth)
privateRoutes.use('/profile', context => {
return new Response(context.user.name)
})
The user property is typed inside handlers registered on privateRoutes.
Combine Routers
Routers are middleware chains, so you can compose public and private route groups into one app.
const publicRoutes = routes()
publicRoutes.use('/status', () => new Response('ok'))
const privateRoutes = routes(auth)
privateRoutes.use('/profile', context => new Response(context.user.id))
const app = chain().use(publicRoutes).use(privateRoutes)
The router returns a response when a handler returns one. If no registered route matches, the parent chain continues.
Note
Path patterns do not need to be ordered from most-specific to least-specific unless two patterns are exactly the same. The matcher chooses the most specific route that matches the request path.
The router is not a Stargate, but /users/:id still gets you through the right ring.