Current State: Manual Middleware Validation

In the previous lesson, we extracted validation into three reusable middleware functions: validateUserId, validateRequiredUserData, and validatePartialUserData. This created three distinct patterns:

  • Parameter validation: Checking URL parameters like user IDs.
  • Required field validation: All fields must be present (POST/PUT).
  • Partial field validation: At least one field must be present (PATCH).

However, these manual middleware functions still have limitations:

  • Poor error messages: Generic errors don’t help users understand specific problems.
  • Limited validation: Basic existence checks don’t validate format, length, or content.
  • Manual maintenance: Adding new validation rules requires writing more if statements.
  • No consistency: Different developers might write validation differently.

Real-World Validation Requirements

Professional APIs need comprehensive validation. For user registration, we might need to validate:

  • Username: 2-50 characters, alphanumeric only.
  • Email: Must be valid email format.
  • Password: 8+ characters with uppercase, lowercase, number, and special characters.
{
  username: "john123",
  email: "john@test.com",
  password: "SecurePass123!",
}

Manual validation would require many lines of if statements and regular expressions - especially for password complexity requirements.

The Schema Validation Solution

Schema validation libraries define data requirements in a declarative way. Instead of writing multiple if statements, we define the exact shape and rules we expect:

const registerSchema = z.object({
  username: z.string().min(2).max(50),
  email: z.email(),
  password: z
    .string()
    .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$/);
});

Benefits of schema validation

  • Declarative: Describe what you want, not how to check it.
  • Comprehensive: Built-in validators for emails, URLs, numbers, etc.
  • Type safety: Automatic TypeScript integration.
  • Reusable: One schema can be used across multiple endpoints.
Tags: