Input Validation & Error Responses

🔗 REST API Lesson 10 Intermediate

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.