When building enterprise-grade backend APIs, separating core business rules from infrastructure, databases, and frameworks is essential for long-term scalability, testability, and team collaboration.
1. Clean Architecture Onion Model
Clean Architecture (introduced by Robert C. Martin) organizes code into concentric rings with the Dependency Inversion Principle at its heart. Dependencies must always point inward toward the Domain:
- Domain Layer: Contains business entities (e.g.,
Student,Course,Invoice), value objects, domain exceptions, and domain events. It has zero external package dependencies. - Application Layer: Defines use cases, MediatR Commands/Queries, interfaces (e.g.,
IApplicationDbContext,IEmailService), DTOs, and validation logic with FluentValidation. - Infrastructure Layer: Implements interfaces defined in the Application layer, such as Entity Framework Core contexts, SQL migrations, Redis caching, and external REST API integrations.
- Presentation / Web API Layer: Exposes HTTP endpoints, Swagger/OpenAPI contracts, CORS policies, and rate-limiting middleware.
2. Command Query Responsibility Segregation (CQRS)
Traditional CRUD controllers often devolve into massive God classes mixing read queries with complex write validations. CQRS splits operations into two distinct pipelines:
- Commands: Mutate state (Create, Update, Delete) and return status or IDs. Handlers encapsulate transaction boundaries and domain validation.
- Queries: Read-only operations that project directly from the database into lightweight DTOs without change tracking overhead (
AsNoTracking()).
3. Pipeline Behaviors & Cross-Cutting Concerns
MediatR pipeline behaviors allow you to implement cross-cutting concerns—such as automated performance logging, structured exception handling, and transaction scopes—around your request handlers without polluting business logic.