When we talk about "clean architecture", many developers immediately think of creating folders like Controllers
, Services
, Repositories
, and so on. While this kind of separation brings some organization, it falls far short of representing the real principles behind clean architecture.
The essence of clean architecture lies in clearly separating responsibilities, low coupling, and most importantly, keeping business rules isolated from any external technology. This means the domain of your application should be at the center—not a detail that depends on the frontend framework, database ORM, or API type.
🔍 What really matters in clean architecture:
- Separating domain from infrastructure
- In a service scheduling system, we kept all logic for availability and timing in a separate project from the WebAPI backend.
- This allowed us to test conflict scenarios without needing to run the database or frontend.
- Well-defined UseCases
- In a financial project using .NET 8, every operation (like "Reconcile Transactions", "Close Quota", "Send to Accounting") became a UseCase.
- This helped new developers quickly understand where to act and made unit testing easier.
- Interfaces and DTOs between layers
- While working with microservices, we defined clear contracts using DTOs between the order service and the billing service.
- This enabled both services to evolve independently without affecting each other.
- Testability and independence
- We used dependency injection with mocks to test complex authentication and business logic scenarios without running any infrastructure.
- Flexibility to adapt to change
- We’ve swapped the UI of a project from Angular to React, and later added a Flutter app—without changing a single line of backend code, thanks to domain focus and abstraction.
Real case: .NET backend, frontend migration from Angular to React
In one of the projects I worked on, we started with an Angular frontend and a .NET backend using the Vertical Slice pattern with UseCases.
Midway through, the frontend team decided to migrate to React for productivity reasons and better compatibility with other company projects.
Thanks to the clear separation of responsibilities in the backend, this transition had zero impact on the business logic. No controller, rule, or entity had to be changed—just the input and output contracts (DTOs).
This was only possible because the backend had no idea who the consumer was. The focus was always on the domain and use cases—not on serving a specific frontend.
Conclusion
Clean architecture isn’t about hype or having a pretty folder structure. It’s about making conscious decisions that allow your application to evolve safely and clearly.
You won't reap the benefits in the first commit, but over time you’ll find it much easier to:
- Maintain the application
- Test isolated components
- Integrate with new frontends or channels (mobile, external APIs)
- Scale your codebase with more developers
What about you?
How do you structure your projects? Do you still organize by technical layers or have you adopted flows based on behavior and domain?
Let me know in the comments — I’d love to exchange ideas on this.
Top comments (0)