Introduction
Bookify is built using a modern, maintainable architecture that combines three powerful design patterns:- Clean Architecture - Separation of concerns with clear dependency rules
- CQRS (Command Query Responsibility Segregation) - Separate read and write operations
- DDD (Domain-Driven Design) - Rich domain models with business logic
Architecture Layers
Bookify follows Clean Architecture’s layered approach with four distinct projects:Layer Responsibilities
Domain Layer
Core business logic, entities, value objects, domain events, and business rules. No external dependencies.
Application Layer
Use cases, CQRS handlers, validation, and application services. Orchestrates domain logic.
Infrastructure Layer
Data access, external services, EF Core, caching, authentication, and third-party integrations.
API Layer
HTTP endpoints, controllers, middleware, and API contracts. Entry point for client requests.
Data Flow Through the System
Here’s how a typical request flows through Bookify:Pipeline Behaviors
MediatR pipeline behaviors execute in order:
- Logging - Logs the request
- Validation - Validates using FluentValidation
- Caching - Checks cache for queries
Handler Execution
The appropriate handler processes the command/query:
- Retrieves entities from repositories
- Executes domain logic
- Persists changes via Unit of Work
Key Benefits
Separation of Concerns
Each layer has a single, well-defined responsibility. Business logic lives in the domain, infrastructure concerns are isolated, and the API layer only handles HTTP concerns.Testability
The architecture makes testing straightforward:- Domain Layer - Pure business logic, no dependencies
- Application Layer - Mock repositories and services
- Infrastructure Layer - Integration tests with real databases
- API Layer - API tests via TestServer
Maintainability
Clear boundaries between layers make the codebase easy to navigate and modify. Changes to infrastructure don’t affect business logic, and vice versa.Flexibility
You can swap implementations without affecting other layers. For example:- Switch from PostgreSQL to SQL Server
- Replace Redis cache with in-memory cache
- Change authentication from Keycloak to Azure AD
All dependencies point inward toward the Domain layer. The Domain never depends on Infrastructure or Application.
Dependency Inversion
Bookify uses dependency inversion extensively. The Application layer defines abstractions (interfaces), and the Infrastructure layer provides implementations:Application Startup
The application is composed at the entry point:What gets registered?
What gets registered?
Application Layer:
- MediatR with all handlers
- Pipeline behaviors (Logging, Validation, Caching)
- FluentValidation validators
- Domain services (PricingService)
- DbContext and EF Core
- Repositories
- Authentication (JWT, Keycloak)
- Authorization (Permissions)
- Caching (Redis)
- Health checks
Next Steps
Clean Architecture
Deep dive into the four layers and dependency rules
CQRS Pattern
Learn how commands and queries are separated
Domain-Driven Design
Explore aggregates, entities, and value objects
Project Structure
Understand the directory organization