Routes and groups
defineRoute(), createRouteGroup(), createRouter() and defineMiddleware(). For a guide, see Routes, Route groups and Middlewares.
defineRoute()
Declares a route on the global router. router.defineRoute() and group.defineRoute() take the same configuration.
Paths
Parameter names match /^[A-Za-z_][A-Za-z0-9_]*$/. Wildcards, optional parameters and regular expressions are rejected. Matching is case-sensitive, ignores trailing slashes, and prefers static segments: see Paths.
Schema
Any Zod 4 schema, classic or mini. The request is validated after the middlewares, and before the handler: req.params, req.query, req.body and req.files hold the parsed values, typed by the output of the schemas. An invalid request gets a 400 VALIDATION_FAILED, with every issue. The response is parsed with schema.response (unknown keys of objects are stripped); a value that does not match is a 500, logged. See Validation.
arrayOf(schema) validates a field sent once or several times (query string, form fields, files) as an array:
Metadata
meta is used by @dotpress/openapi, and available to plugins in app.routes.
createRouteGroup()
Creates a group on the global router. router.createGroup() and group.createGroup() take the same arguments.
Parameters of the prefix (/tenants/:tenant) are typed in the routes of the group, and so are the context properties guaranteed by its middlewares. See Route groups.
createRouter()
An isolated registry of routes, mounted with createApp({ routers }).
globalRouter is the router of defineRoute(), createRouteGroup() and registerResponseFilter(), mounted when createApp() has no routers.
defineMiddleware()
A middleware returns nothing to continue, or an HttpError or a response to stop the request. Throwing an HttpError works too.
A plain function (ctx) => … is a middleware too, without guarantees. Middlewares run before validation: ctx.req holds the raw values. See Middlewares.
Response filters
A filter transforms the JSON result of a success, after the response validation. Filters run in this order: those of createApp({ responseFilters }), of the plugins, then of the router (router.addResponseFilter(), or registerResponseFilter() for the global router). Errors and other response helpers do not go through filters. See Response filters.