Codecs and Serialization
Use codecs and serialization with the current published Askr packages.
@askrjs/askr0.0.59
How to use codecs and serialization
Define an executable schema once and reuse its jsonSchema representation in the HTTP contract and generated-client workflow.
- Import the published @askrjs/askr entrypoint.
- Keep codecs and serialization configuration next to the component, route, or server composition root that owns it.
- Handle pending, unavailable, cancellation, and failure states, then verify the production path.
import { schema } from '@askrjs/schema';
export const projectInput = schema.object({
name: schema.string({ minLength: 1 }),
ownerId: schema.uuid(),
});
const parsed = projectInput.safeParse(await request.json());
const jsonSchema = projectInput.jsonSchema;Request encoding
A Codec pairs a kind — json, text, urlEncoded, multipart, blob, arrayBuffer, stream, empty, or content — with the media types it produces and an optional validator. Calling .body(codec) on an endpoint builder wires that codec into request serialization, and content({ "application/json": json(), "multipart/form-data": multipart() }) lets a single endpoint accept more than one request format.
Response decoding
returns(codec) and returns(status, codec) register the codec used to decode each response status; the client picks whichever codec matches the response's actual status and content type. 204, 205, and HEAD responses must be declared with empty() — anything else against those statuses is treated as an unexpected body and fails decoding.
Dates and custom values
Because a validator only needs a safeParse(value) method, date parsing, custom scalar coercion, or a third-party validation library can be dropped straight into json(schema), a parameter spec's validator, or any other codec slot without an adapter layer. Whatever the validator's safeParse returns as data is what gets serialized on the way out and returned to the caller on the way in.
Failure diagnostics
A response with no codec registered for its status, a content type the registered codec doesn't declare, a payload that fails safeParse, or a non-empty body where empty() was required all produce a FailureResult with kind: "decode" rather than a thrown exception. The underlying cause — the validator's error, or a description of the mismatch — is available on result.error for logging or a bug report.