Curso de Spring Boot
Cuando las aplicaciones crecen, el código puede volverse difícil de mantener.
Por eso es importante organizar bien el proyecto desde el principio.
En este capítulo aprenderemos:
- la arquitectura por capas
- cómo organizar paquetes
- qué es un Controller
- qué es un Service
- qué es un Repository
- qué son los DTO
Esta arquitectura es la más usada en proyectos Spring Boot profesionales.
4.1 Arquitectura por capas
La arquitectura más común en Spring Boot es la arquitectura en capas.
El flujo típico de una aplicación es:
Cliente
↓
Controller
↓
Service
↓
Repository
↓
Base de datos
Cada capa tiene una responsabilidad diferente.
4.2 Estructura recomendada de paquetes
Una estructura típica es esta:
com.example.app
controller
service
repository
entity
dto
config
Ejemplo completo:
src/main/java/com/example/app
controller
UserController.java
service
UserService.java
repository
UserRepository.java
entity
User.java
dto
UserDTO.java
Esta organización hace el código mucho más claro.
4.3 Controller
El Controller recibe las peticiones HTTP.
Por ejemplo:
GET /users
POST /users
DELETE /users
El controller no debe contener lógica compleja.
Su función es:
- recibir peticiones
- llamar al service
- devolver respuesta
Ejemplo
1@RestController 2@RequestMapping("/users") 3public class UserController { 4 5 private final UserService service; 6 7 public UserController(UserService service) { 8 this.service = service; 9 } 10 11 @GetMapping 12 public List<User> getUsers() { 13 return service.getAllUsers(); 14 } 15 16}
El controller simplemente llama al service.
4.4 Service
La capa Service contiene la lógica de negocio.
Ejemplos de lógica de negocio:
- validar datos
- aplicar reglas
- procesar información
- coordinar repositorios
Ejemplo
1@Service 2public class UserService { 3 4 private final UserRepository repository; 5 6 public UserService(UserRepository repository) { 7 this.repository = repository; 8 } 9 10 public List<User> getAllUsers() { 11 return repository.findAll(); 12 } 13 14}
El service utiliza el repository para acceder a la base de datos.
4.5 Repository
El Repository se encarga de acceder a la base de datos.
En Spring Boot normalmente usamos Spring Data JPA.
Ejemplo:
1@Repository 2public interface UserRepository extends JpaRepository<User, Long> { 3 4}
Esto automáticamente genera:
findAll()
findById()
save()
delete()
Sin escribir código.
4.6 Entity
Una Entity representa una tabla de la base de datos.
Ejemplo:
Tabla:
users
Entidad:
1@Entity 2public class User { 3 4 @Id 5 @GeneratedValue 6 private Long id; 7 8 private String name; 9 10 private String email; 11 12}
Cada objeto corresponde a un registro de la tabla.
4.7 DTO (Data Transfer Object)
Un DTO es un objeto que se usa para transferir datos entre capas.
Se utiliza para evitar enviar entidades directamente.
Por qué no devolver entidades
Si devolvemos entidades:
- podemos exponer datos sensibles
- podemos generar problemas de rendimiento
- podemos acoplar la API a la base de datos
Por eso se usan DTOs.
Ejemplo DTO
1public class UserDTO { 2 3 private Long id; 4 private String name; 5 6}
Este DTO no incluye el email.
4.8 Flujo completo de una petición
Supongamos esta petición:
GET /users
El flujo sería:
Cliente
↓
UserController
↓
UserService
↓
UserRepository
↓
Base de datos
Después vuelve la respuesta.
4.9 Ejemplo completo
Entity
1@Entity 2public class User { 3 4 @Id 5 @GeneratedValue 6 private Long id; 7 8 private String name; 9 10}
Repository
1@Repository 2public interface UserRepository extends JpaRepository<User, Long> { 3 4}
Service
1@Service 2public class UserService { 3 4 private final UserRepository repository; 5 6 public UserService(UserRepository repository) { 7 this.repository = repository; 8 } 9 10 public List<User> getUsers() { 11 return repository.findAll(); 12 } 13 14}
Controller
1@RestController 2@RequestMapping("/users") 3public class UserController { 4 5 private final UserService service; 6 7 public UserController(UserService service) { 8 this.service = service; 9 } 10 11 @GetMapping 12 public List<User> getUsers() { 13 return service.getUsers(); 14 } 15 16}
4.10 Ventajas de esta arquitectura
Esta arquitectura tiene muchas ventajas.
Código más organizado
Cada clase tiene una función clara.
Más fácil de mantener
Podemos modificar una capa sin afectar a otras.
Más fácil de probar
Podemos probar services sin controllers.
Más fácil de escalar
Las aplicaciones grandes siguen esta estructura.
4.11 Buenas prácticas
Algunas recomendaciones importantes.
Controller ligero
El controller debe ser simple.
❌ Incorrecto:
controller con lógica compleja
✔ Correcto:
controller llama al service
Service con lógica
La lógica de negocio debe estar en el service.
Repository solo para datos
El repository solo accede a la base de datos.
Usar DTOs
Evita devolver entidades directamente.
- Loading...