Course contentsShow
← Node.js
Lesson 692 of 1,9807. Web Framework Architecture and MiddlewareFree lesson

Value Object Validation

Encapsulate data validation rules within dedicated value objects for cleaner routes.

In this lesson, you will learn how to shift data validation from your route handlers into dedicated "Value Objects" to keep your web architecture clean and maintainable.

The Problem: Cluttered Routes

When building web APIs, we often fall into the trap of writing validation logic directly inside our controllers or route handlers. If you are checking an email format, validating a password length, or ensuring a UUID is valid, you end up with "fat" routes filled with if/else statements. This makes your routes hard to read and impossible to reuse.

The Solution: Value Objects

A Value Object is a small, immutable object that represents a specific piece of domain data. Its primary responsibility is to ensure that it only exists if the data inside it is valid. Instead of passing a raw string to your service layer, you pass an instance of a Value Object that has already "vouched" for its own integrity.

Consider this example of a UserEmail value object:

class UserEmail {
  constructor(email) {
    if (!email.includes('@')) {
      throw new Error('Invalid email format');
    }
    this.value = email;
  }
}

// Inside your route:
app.post('/register', (req, res) => {
  try {
    const email = new UserEmail(req.body.email);
    // Proceed, knowing the email is guaranteed to be valid
    userService.register(email);
  } catch (err) {
    res.status(400).send(err.message);
  }
});

Why this works

By moving the validation into the constructor, the rest of your application can trust that any UserEmail object it receives is valid. You no longer need to repeat the "is this email valid?" check in your service layer or database layer. If the input is invalid, the object simply fails to be created, preventing dirty data from ever entering your core logic.

This technique drastically simplifies your route handlers, as they now act only as a bridge between the HTTP request and the domain logic, delegating the "truth" of the data to the objects themselves.

Key Takeaway: Encapsulate data validation logic within Value Objects to ensure that your application only processes data that is guaranteed to be valid.