Input Validation & Error Responses
Never trust client input. Thorough input validation prevents security vulnerabilities, database corruption, and confusing bugs. Well-structured error responses make your API easy to debug and integrate with.
1 Validation with express-validator
JavaScript — Input Validation Middleware
const { body, param, query, validationResult } = require("express-validator");
// Validation rules for POST /users
const createUserRules = [
body("name")
.trim()
.notEmpty().withMessage("Name is required")
.isLength({ min: 2, max: 100 }).withMessage("Name must be 2-100 chars"),
body("email")
.isEmail().withMessage("Valid email is required")
.normalizeEmail(),
body("password")
.isLength({ min: 8 }).withMessage("Password must be at least 8 characters")
.matches(/[A-Z]/).withMessage("Must contain at least one uppercase letter")
.matches(/[0-9]/).withMessage("Must contain at least one number"),
body("role")
.optional()
.isIn(["user", "editor", "admin"]).withMessage("Invalid role")
];
// Middleware to handle validation errors
function validate(req, res, next) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({
success: false,
error: {
code: "VALIDATION_ERROR",
message: "Input validation failed",
fields: errors.array().reduce((acc, err) => {
acc[err.path] = err.msg;
return acc;
}, {})
}
});
}
next();
}
// Apply to route
router.post("/users", createUserRules, validate, createUser);
2 Standard Error Response Format
JSON — Error Response Examples
// 400 Bad Request
{
"success": false,
"error": { "code": "BAD_REQUEST", "message": "Request body is malformed JSON" }
}
// 422 Validation Error (most useful — field-level details)
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Input validation failed",
"fields": {
"email": "Valid email is required",
"password": "Must contain at least one uppercase letter"
}
}
}
// 404 Not Found
{
"success": false,
"error": { "code": "NOT_FOUND", "message": "Product with id 99 not found" }
}
// 429 Rate Limited
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Try again in 60 seconds.",
"retryAfter": 60
}
}
3 Code Challenge
Challenge: Write validation rules for a
POST /products endpoint: name (string, 3-200 chars), price (integer, min 0), category (one of: electronics, clothing, books, food), inStock (boolean). Return field-level errors in a unified error envelope.