Validate a request body
Reject malformed JSON bodies before your handler runs and read typed fields from scope.input or ctx.extract.
AI generated, pending review
You want a POST route that rejects a malformed JSON body with a 400 before your handler runs, and hands the handler typed, validated fields. Put a body schema on the route descriptor.
Inline route
Section titled “Inline route”- Define a
bodyschema from@flare-ts/lib/schema. - Pass it in route options as
{ body: schema }. - Read the validated body from
scope.input.body.
import { FlareHost, FlareResponse } from "@flare-ts/core";import { node } from "@flare-ts/core/node";import { schema, str, int } from "@flare-ts/lib/schema";
const host = new FlareHost(node);
host.http.post( "/users", { body: schema({ name: str.min(1), age: int.min(0) }) }, (_ctx, scope) => { const { body } = scope.input; return new FlareResponse(201, { name: body.name, age: body.age }); },);
const app = host.build();app.run();Body validation runs after before middleware and immediately before the handler. A present-but-invalid body returns 400 with field errors before the handler runs. An empty or missing body arrives as body === null and is not rejected, so guard for it when a field is required.
Controller route
Section titled “Controller route”Group descriptors in httpContract and use ctx.extract:
import { ControllerBase, FlareHost, httpContract } from "@flare-ts/core";import { Post } from "@flare-ts/core/decorators";import { node } from "@flare-ts/core/node";import { model, str, int } from "@flare-ts/lib/schema";
class CreateUser extends model({ name: str.min(1), age: int.min(0) }) {}
const UserContract = httpContract({ create: { body: CreateUser },});
class UsersController extends ControllerBase { public static override deps = []; public static override state = []; public static override contract = UserContract;
@Post("") create() { const { body } = this.ctx.extract(UserContract.create); return this.created({ name: body.name, age: body.age }); }}
const host = new FlareHost(node);host.http.controller("/users", UsersController);
const app = host.build();app.run();- Validation happens once per request at the boundary. You don’t re-validate inside the handler.
- Add
routeandqueryto the same descriptor. Inline handlers read all fields fromscope.input. - To cap body size, add
maxBodyBytesto the descriptor. Oversized bodies return 413.
Related
Section titled “Related”- HTTP contracts
- Request limits and bodies
- Schema: primitives and
model()