Construir una aplicación bien organizada desde el inicio marca la diferencia entre un proyecto mantenible y uno que se vuelve caótico con el tiempo. Aquí se explica cómo estructurar un proyecto Spring Boot usando una arquitectura por capas orientada al dominio, separando responsabilidades de forma clara para que cada componente tenga un propósito definido.
¿Qué es la arquitectura por capas orientada al dominio?
Esta arquitectura divide la aplicación en tres capas principales, cada una con una responsabilidad específica. La idea central es que el dominio sea el corazón de la aplicación, y las demás capas giren alrededor de él.
- Capa de dominio: contiene los objetos que representan el contexto del negocio, en este caso un supermercado. Aquí viven los DTOs (objetos de transferencia de datos), los objetos de dominio, los servicios y las especificaciones de repositorios [0:28].
- Capa web: aloja los controladores de la API, es decir, los puntos de entrada que reciben las peticiones del cliente [1:20].
- Capa de persistencia: se encarga de interactuar directamente con la base de datos. Contiene los repositorios y los entities [1:30].
¿Qué papel cumplen los servicios en esta arquitectura?
Los servicios funcionan como un puente entre los controladores de la API y la capa de persistencia [0:42]. Cuando un controlador recibe una petición, no accede directamente a la base de datos. En su lugar, delega la lógica al servicio correspondiente, que a su vez llama al repositorio específico que necesite.
Este patrón garantiza que la lógica de negocio esté centralizada y no dispersa entre controladores y repositorios.
¿Qué son las especificaciones de repositorio?
Dentro de la capa de dominio se definen interfaces que actúan como contratos o reglas de juego [1:00]. Estas especificaciones indican qué operaciones debe cumplir la persistencia para intervenir entre los objetos de dominio y la base de datos. La implementación concreta de estas interfaces vive en la capa de persistencia.
Los entities son las clases que mapean las tablas de la base de datos [1:42]. Cada entity representa una tabla y sus atributos corresponden a las columnas.
¿Cómo fluye una petición dentro de esta arquitectura?
El recorrido de una solicitud sigue un camino lineal y predecible [1:52]:
- Un cliente hace un llamado a un controlador de la API.
- El controlador invoca al servicio que contiene la lógica necesaria para esa operación.
- El servicio acude al repositorio específico que requiere.
- El repositorio ejecuta la gestión correspondiente en la base de datos.
Esta separación hace que cada capa sea independiente y fácil de probar o modificar sin afectar a las demás.
¿Cómo se crea la estructura de paquetes en el proyecto?
Dentro del proyecto en el IDE, se crean los paquetes siguiendo la jerarquía de capas [2:14]:
domain → contiene los subpaquetes dto, repository (para las especificaciones) y service.
web → contiene el subpaquete controller.
persistence → contiene los subpaquetes entity y crud [3:22].
El paquete crud almacena los crud repositorios de la aplicación, un concepto que se relaciona con las operaciones básicas de crear, leer, actualizar y eliminar datos.
¿Por qué eliminar el controlador de ejemplo?
El Hola Mundo Controller creado anteriormente solo sirvió para verificar el funcionamiento inicial de la aplicación [3:38]. Al tener la nueva estructura lista, se mueve al paquete web.controller y luego se elimina con la opción safe delete, asegurando que no queden referencias rotas en el proyecto [3:57].
Con esta organización, el proyecto queda preparado para escribir código de forma ordenada, donde cada archivo tiene un lugar lógico y el mantenimiento a largo plazo resulta mucho más sencillo. En la siguiente sesión se aborda el concepto de JPA, que será fundamental para la capa de persistencia.