Routing
Routes are an object. Each key is a method and a path, and each value is the handler for it, usually made with defineMiddleware.
const routes = {
'GET /users': listUsers,
'POST /users': createUser,
'GET /users/me': showCurrentUser,
'GET /users/:id': showUser,
'GET /users/:id/posts/:post': showPost,
}The method can be written in any case. A segment starting with : matches any one non-empty segment.
How a request is matched
GET /healthcheckis answered first. See healthchecks.- A trailing slash is redirected away:
/users/gets a301to/users, keeping the query. Only/itself keeps its slash. - An exact match wins:
GET /users/megoes toshowCurrentUser, notshowUser. - Patterns with parameters come next, the ones with the most segments first, so
/users/:id/posts/:postis tried before/users/:id. A pattern only matches a path with the same number of segments. - Anything else goes to the
ERROR 404route.
The query string never affects matching.
Reading parameters
The router finds the route but doesn't store the parameters. Read them from the request with the route's pattern:
const showUser = defineMiddleware([
async ({ incomingMessage, serverResponse }) => {
const { id } = incomingMessage.useUrlParams('/users/:id')
serverResponse.sendOKJSONResponse(await findUser(id))
},
])Values are URL-decoded. If the path doesn't fit the pattern, useUrlParams returns {}.
Not found
Requests that match nothing get 404 page not found as text, and the server logs them at info. To send something else, such as an HTML page, give a route for the ERROR 404 key:
routes: {
'ERROR 404': async ({ serverResponse }) => {
serverResponse.sendNotFoundHTMLResponse(renderNotFoundPage())
},
}Preflight requests
CORS preflights are OPTIONS requests, and they're routed like any other: give the path an OPTIONS route. See @webframe/use-cors-headers.