In this post, I’m going to discuss how to validate inputs to maintain the integrity of our business domain. Specifically, I’ll assume we are working with entities and aggregates, which are tactical patterns in Domain-Driven Design (DDD).
There are situations, where we might need to pass an entity directly to a method within our aggregate. Let’s look at an example:
class Order {
constructor(
private id: OrderId,
private requestId: RequestId,
// Other properties...
) {}
}
Consider a method like this:
class Order {
processRequest(request: Request): void {
if (!this.belongsToRequest(request)) {
throw new RequestDoesNotBelongToOrder(request.getId());
}
// Rest of the code
}
}
private belongsToRequest(request: Request): boolean {
return this.requestId.equal(request.getId())
}
As mentioned, there are cases where we might need to pass another entity directly (in our case Request) into the aggregate method. It’s crucial in such situations to ensure that our domain maintains its integrity by validating the entity before proceeding.
In the example above, the method processRequest
first checks if
the given request actually belongs to the order. This is achieved through the
belongsToRequest
method, which compares the
requestId
of the order with the requestId
of the
incoming request. If they don’t match, an exception is thrown, indicating that
the request does not belong to the order.
This guard clause is essential to maintain the integrity of our domain. By encapsulating this logic within the aggregate, we ensure that any operation on the aggregate respects the domain's invariants and business rules.
Ensuring the integrity of our domain models is critical for several reasons:
By following these principles, we maintain a clean and robust domain model.
Remember, always validate inputs and operations within your aggregates to uphold the business rules and keep your domain model in a consistent state.