La clean architecture es un patrón arquitectónico muy usado en .NET para construir APIs escalables y mantenibles. Si trabajas con APIs en .NET y quieres ordenar tu código por responsabilidades, esta guía te muestra cómo distribuir capas y proyectos siguiendo este patrón.
¿Qué es clean architecture y por qué importa en .NET?
Clean architecture propone una distribución específica de responsabilidades para que tu API crezca sin perder orden. La idea central es separar capas con roles claros, de modo que puedas navegar el proyecto con facilidad incluso cuando se vuelve grande.
En la propuesta original existen tres capas principales que vale la pena entender antes de saltar al código.
¿Cuáles son las capas de clean architecture?
- Capa de presentación: puede ser una app web completa o, en este caso, una API. Aquí viven los controladores, que actúan como interfaz hacia los clientes.
- Capa de aplicación: distribuye la lógica de la app, los contratos o interfaces que se comunican con datos, y los casos de uso, como cálculos matemáticos o comportamientos específicos.
- Capa de dominio: contiene el negocio, las entidades que representan la información del servidor y la estructura para conectarse a recursos como archivos o bases de datos.
¿Qué resuelve clean architecture en una API? Te da un orden claro entre presentación, lógica y datos para que el proyecto sea escalable y mantenible sin importar cuánto crezca.
¿Cómo se traduce clean architecture en un proyecto .NET?
Al llevar este patrón a .NET, terminas con cuatro proyectos dentro de la solución: API, application, domain e infrastructure. Cada uno cumple un rol distinto y se referencian entre sí de forma controlada.
¿Qué va en cada proyecto: API, application, domain e infrastructure?
- API: contiene los controladores, los middleware, la autenticación y la configuración general como la documentación con Swagger. Es la capa de presentación hacia los clientes que consumen la API.
- Application: aloja los contratos (interfaces), utilidades y lógica particular que la API necesita. Define qué se debe hacer, no cómo.
- Domain: en el ejemplo solo guarda los modelos que conectan con la base de datos, como TaskItem y User.
- Infrastructure: implementa los contratos definidos en application, contiene el AppDbContext de Entity Framework, los servicios como TaskService y UserService, y la configuración de inyección de dependencias.
La relación es clave: infrastructure referencia a application para leer las interfaces, y luego construye la implementación concreta. Por eso encuentras TaskService y UserService en infrastructure, mientras que sus interfaces viven en application.
¿Cómo configurar las referencias entre proyectos sin romper la separación?
En un proyecto .NET con clean architecture, el proyecto de API normalmente referencia application, domain e infrastructure. La referencia a infrastructure es obligatoria porque desde Program.cs registras el AppDbContext y los servicios.
Sin embargo, referenciar domain directamente desde API no es ideal, aunque funcione y se haga en muchos proyectos por practicidad.
¿Por qué deberías evitar exponer entidades de dominio en la API?
Las entidades de dominio, como TaskItem, están pensadas para representar datos de base de datos, no para ser la respuesta final hacia el cliente. Mezclarlas obliga a la API a depender de detalles que deberían estar ocultos.
La mejor práctica es crear dentro de application una carpeta llamada ViewModels o DTOs con clases dedicadas a la respuesta. Así, infrastructure se encarga de mapear cada entidad de dominio al ViewModel o DTO correspondiente antes de devolver datos.
¿Qué es un DTO o ViewModel en este contexto? Es una clase que representa la respuesta final que la API entrega al cliente, con propiedades y configuración diferentes a la entidad de base de datos.
Con ese cambio puedes eliminar la referencia directa de API a domain y dejar que cada capa hable solo con quien debe.
¿Qué reto puedes resolver para practicar clean architecture?
El ejercicio propuesto es claro y muy útil para afianzar el patrón. Toma el proyecto base y aplica estos pasos:
- Crea dentro de application una carpeta ViewModels o DTOs con las clases que representen las respuestas finales.
- Modifica los servicios en infrastructure para que mapeen las entidades de dominio a esos ViewModels o DTOs.
- Elimina la referencia del proyecto API hacia domain, dejando solo application e infrastructure.
- Ejecuta todos los endpoints y verifica que el comportamiento sea idéntico al del proyecto original de cursos API.
Al terminar, vas a tener una estructura más limpia, con responsabilidades bien separadas y un proyecto preparado para crecer sin convertirse en un nudo. ¿Ya intentaste aplicarlo en alguna API tuya? Cuéntame en los comentarios cómo distribuiste las capas.