Reusable schema validation middleware with Zod or Joi
schema-driven validation as middleware.
define a schema (email, password min 8, optional firstName), write a factory middleware that validates req.body, returns 400 with messages on failure, and assigns the parsed value on success.
WHAT THIS TESTS Whether you can express validation rules as a schema and apply them reusably at the route boundary, returning useful errors.
A GOOD ANSWER COVERS You first define a schema. With Zod that is z.object with email being z.string().email(), password being z.string().min(8), and firstName being z.string().optional(); with Joi it is Joi.object with email Joi.string().email().required(), password Joi.string().min(8).required(), and firstName Joi.string().optional(). Then you write a factory middleware, validate(schema), that returns an Express middleware. Inside, it parses req.body against the schema. On failure it responds 400 with the structured list of field errors so the client knows exactly what was wrong. On success it assigns the parsed, type-coerced result back to req.body (or req.validated) and calls next, so the controller works with validated data only. You mount validate(registerSchema) before the handler, keeping the controller free of validation logic.
COMMON WRONG ANSWERS Hardcoding checks inside each controller, throwing a 500 on validation failure, discarding the parsed output, or making firstName required by accident.
LIKELY FOLLOW-UPS Validating params and query too, abortEarly versus collecting all errors, stripping unknown keys, and sharing the schema with the client.
ONE CONCRETE EXAMPLE const validate = schema => (req, res, next) => { const result = schema.safeParse(req.body); if (!result.success) return res.status(400).json({ errors: result.error.flatten().fieldErrors }); req.body = result.data; next(); }; then app.post('/register', validate(registerSchema), registerUser). A body missing a valid email returns 400 with a per-field message, and the controller only ever runs on clean input.
Read the original → digitalocean.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.