Transform input data during validation with Zod schemas
Transformations allow you to modify data as it flows through validation. This is especially useful for converting string parameters to numbers, parsing dates, normalizing data, and more.
Use .transform() to convert validated data into a different format:
Copy
Ask AI
import { z } from "zod";const getUserEndpoint = endpointsFactory.buildVoid({ input: z.object({ id: z.string().transform((id) => parseInt(id, 10)), }), handler: async ({ input: { id }, logger }) => { logger.debug("id", typeof id); // number // id is now a number, not a string },});
You can chain validators before and after transformations:
Copy
Ask AI
import { z } from "zod";import { defaultEndpointsFactory } from "express-zod-api";const updateUserEndpoint = defaultEndpointsFactory.build({ method: "patch", input: z.object({ id: z .string() .regex(/^\d+$/, "ID must be numeric") .transform((id) => parseInt(id, 10)) .refine((id) => id >= 0, "ID must be non-negative"), }), output: z.object({ success: z.boolean(), }), handler: async ({ input }) => { // id is validated as string, transformed to number, then validated as number return { success: true }; },});
Here’s a complete example from the Express Zod API source showing transformation in action:
Copy
Ask AI
import { z } from "zod";import { ez, defaultEndpointsFactory } from "express-zod-api";const updateUserEndpoint = defaultEndpointsFactory.build({ method: "post", input: z.object({ // Path parameter arrives as string id: z .string() .example("12") .transform((value) => parseInt(value, 10)) .refine((value) => value >= 0, "should be greater than or equal to 0"), name: z.string().nonempty(), birthday: ez.dateIn(), // Transforms ISO string to Date }), output: z.object({ name: z.string(), createdAt: ez.dateOut(), // Transforms Date to ISO string }), handler: async ({ input }) => { // input.id is a number // input.birthday is a Date return { name: input.name, createdAt: new Date("2022-01-22"), }; },});