Eliminating Mapping and Redundant Validation in Domain-Centric APIs with JsonConverters and ModelBinding
Numerous applications are designed adhering to the principles of Clean Architecture and Domain-Driven Design (DDD). They have a rich domain models that protect the business invariants.
In most cases, this manifests in an application that has a Core
library that contains Aggregates
, Entities
, and Value-types
. Following the clean architecture principles, it will contain UseCases
too. They are the implementation of the business-processes the application automates.
The general line of thought here, is that UseCases
does not contain business logic that is irrelevant to the process.
For instance, when a customer places an order in an online store, the UseCase
responsible for this process should not be burdened with validating the correctness of the received EAN (European Article Number) parameter. Instead, the UseCase
should expect an EAN parameter that already encapsulates the applicable business rules.
Implementing UseCases and ValueTypes
To provide a more concrete example, let’s examine the following code snippet:
public class PlaceOrderUseCase {
// constructor and fields left out for brevety
public async Task PlaceOrder(EAN productId, int quantity)
{
var stock = await _stockRepository.Get(productId);
if (!stock.isInStock(quantity)) {
throw new…