KosmoJS extends the standard Koa/Hono context with two additions: a unified bodyparser API and ctx.validated for type-safe access to validated request data.
π Unified Bodyparser β
ctx.bodyparser works the same regardless of framework:
ts
await ctx.bodyparser.json() // JSON request body
await ctx.bodyparser.form() // URL-encoded or multipart form
await ctx.bodyparser.raw() // raw body bufferResults are cached - calling the same parser multiple times doesn't re-parse the request.
In practice you rarely call this directly. Define a validation schema in your handler and the appropriate parser runs automatically, placing the result in ctx.validated.
β Validated Data Access β
ctx.validated holds the validated, typed result for each target you defined:
ts
export default defineRoute(({ POST }) => [
POST<{
json: Payload<CreateUser>,
query: { limit: number },
headers: { "x-api-key": string },
}>(async (ctx) => {
const user = ctx.validated.json; // validated JSON body
const limit = ctx.validated.query; // validated query params
const apiKey = ctx.validated.headers; // validated headers
}),
]);π Route Parameters β
Validated params are available at ctx.validated.params, typed according to your refinements:
ts
export default defineRoute<"users/[id]", [number]>(({ GET, POST }) => [
GET<{
query: { page: string; filter?: string },
}>(async (ctx) => {
const { id } = ctx.validated.params; // number
const { page, filter } = ctx.validated.query;
}),
POST<{
json: Payload<User>,
}>(async (ctx) => {
const { id } = ctx.validated.params; // number
const user = ctx.validated.json;
}),
]);The underlying ctx.params (Koa) and ctx.req.param() (Hono) still exist if you need the raw strings.