Validation with Zod
Zod is the default validator most DaloyJS apps reach for: chainable schemas, mature ecosystem, and a huge community. Zod implements Standard Schema, so DaloyJS picks it up without any adapter.
Prefer a more modular, tree-shakeable API? See Validation with Valibot. Both work the same way at the framework level.
- you writeZod schemaz.object({ ... })
- runtimeRequest & response validation422 on invalid input
- compile timeInferred handler typesz.infer<typeof ...>
- specOpenAPI JSON Schemastays in sync via pnpm gen
Install
What gets validated
For each route you can declare schemas for:
request.params: decoded path parameters. They start as strings, so usez.coerce.number(),z.uuid(), or enums when you need stronger shapes.request.query: query string values. Repeated keys become arrays before validation.request.headers: request headers as lower-case names.request.body: parsed request bodies. The body is only read when declared.responses[status].body: typed and validated responses.
A complete route
On invalid input, DaloyJS returns 422 Unprocessable Entity as RFC 9457 problem+json with an errors array of per-issue path and message records.
Zod coercion for strings
Path params, query values, headers, and urlencoded form values arrive as strings before schema validation. Use Zod coercion or transforms when you want numbers, booleans, or dates in the handler.
Body limits and content types
When a route declares request.body, DaloyJS will also enforce:
- Content-Length and streamed size against
app.bodyLimitBytes→ 413. - Content-Type against the route's
acceptslist, or globalallowedContentTypesif set → 415. - Default accepted body types:
application/json,application/x-www-form-urlencoded, andmultipart/form-data. - Prototype-pollution-safe parsing for JSON, query strings, urlencoded forms, and multipart forms.
JSON bodies validate as parsed JSON. Urlencoded bodies validate as an object built from URLSearchParams. Multipart bodies validate as an object built from Request.formData(). For a custom text media type, opt in with accepts and validate a z.string() body.
Response validation
When a response schema is declared, DaloyJS validates the handler return before serializing it. Zod object schemas strip unknown keys by default, so the validated value also prevents undeclared fields from leaking to clients. Use z.looseObject() only when extra keys are part of the intended response contract.
Type inference
The handler context is fully typed: body, params, query, and headers are inferred from your schemas. The return value is also typed; TypeScript reports an error if you return a status not declared in responses.
See also
- Validation overview: how validators plug in via Standard Schema.
- Validation with Valibot: the tree-shakeable alternative.
- OpenAPI generation: how schemas become a spec.
- Errors & problem+json: the error contract.