Curso de Spring Boot

Cuando los proyectos crecen mucho (miles de líneas de código), una mala organización del proyecto provoca:

  • código difícil de mantener
  • dependencias cruzadas
  • errores difíciles de encontrar
  • dificultad para añadir nuevas funcionalidades

Por eso las empresas utilizan estructuras de proyecto profesionales.


21.1 Estructura básica (proyectos pequeños)

En proyectos simples suele usarse esta estructura:

1com.example.app
2
3controller
4service
5repository
6entity
7dto
8config

Ejemplo:

1controller
2   UserController
3
4service
5   UserService
6
7repository
8   UserRepository

Esta estructura funciona bien para proyectos pequeños.


21.2 Problema cuando el proyecto crece

Imagina que el sistema tiene:

  • usuarios
  • cursos
  • pagos
  • notificaciones
  • reportes

La estructura quedaría así:

1controller
2   UserController
3   CourseController
4   PaymentController
5   ReportController
6
7service
8   UserService
9   CourseService
10   PaymentService
11   ReportService

Esto provoca:

  • carpetas enormes
  • difícil localizar código
  • mezcla de dominios

21.3 Estructura por módulos (recomendada)

Las empresas suelen organizar por dominio o funcionalidad.

Ejemplo:

1com.example.app
2
3user
4   controller
5   service
6   repository
7   entity
8   dto
9
10course
11   controller
12   service
13   repository
14   entity
15   dto
16
17payment
18   controller
19   service
20   repository
21   entity

Esto mejora:

  • organización
  • mantenibilidad
  • escalabilidad

21.4 Ejemplo real

1com.example.courseapp
2
3config
4security
5exception
6
7user
8   controller
9   service
10   repository
11   entity
12   dto
13
14course
15   controller
16   service
17   repository
18   entity
19   dto
20
21enrollment
22   controller
23   service
24   repository
25   entity

Cada módulo contiene todo lo necesario para esa funcionalidad.


21.5 Separar capa de infraestructura

En proyectos grandes también se separa:

1domain
2application
3infrastructure

Ejemplo:

1domain
2   model
3   repository
4
5application
6   service
7   usecase
8
9infrastructure
10   controller
11   persistence
12   config

Esto se usa en:

  • Clean Architecture
  • Arquitectura Hexagonal

21.6 Ejemplo completo profesional

1com.example.app
2
3config
4security
5exception
6
7user
8   controller
9   service
10   repository
11   entity
12   dto
13   mapper
14
15course
16   controller
17   service
18   repository
19   entity
20   dto
21   mapper
22
23enrollment
24   controller
25   service
26   repository
27   entity

21.7 Usar Mapper para convertir DTO

En proyectos grandes se usan mappers.

Ejemplo con MapStruct.


DTO → Entity

1@Mapper(componentModel = "spring")
2public interface UserMapper {
3
4    User toEntity(UserDTO dto);
5
6    UserDTO toDTO(User user);
7
8}

Esto evita escribir conversiones manuales.


21.8 Separar lógica de negocio

Un error común es poner lógica en los controllers.

Incorrecto:

1@PostMapping
2public User create(@RequestBody UserDTO dto) {
3
4    User user = new User();
5
6    user.setName(dto.getName());
7
8    return repository.save(user);
9
10}

Correcto:

1@PostMapping
2public User create(@RequestBody UserDTO dto) {
3
4    return service.createUser(dto);
5
6}

La lógica debe estar en services.


21.9 Manejo global de errores

En proyectos profesionales se usa un GlobalExceptionHandler.


Ejemplo

1@RestControllerAdvice
2public class GlobalExceptionHandler {
3
4    @ExceptionHandler(RuntimeException.class)
5    public ResponseEntity<String> handle(RuntimeException ex) {
6
7        return ResponseEntity
8                .status(HttpStatus.BAD_REQUEST)
9                .body(ex.getMessage());
10
11    }
12
13}

Esto centraliza los errores.


21.10 Paginación en APIs

Nunca devolver listas enormes.


Ejemplo

1@GetMapping
2public Page<User> getUsers(Pageable pageable) {
3
4    return repository.findAll(pageable);
5
6}

Petición:

1/users?page=0&size=10

21.11 Logging profesional

Usar SLF4J.

1private static final Logger log =
2        LoggerFactory.getLogger(UserService.class);

Ejemplo:

1log.info("Creando usuario {}", email);

21.12 Configuración por entornos

Separar configuración:

1application-dev.properties
2application-prod.properties

Activar perfil:

1spring.profiles.active=dev

21.13 Buenas prácticas profesionales

usar DTO

Nunca devolver entidades directamente.


separar capas

Controller → Service → Repository.


validación de datos

Usar anotaciones:

1@NotNull
2@Email
3@Size

manejar errores globalmente

Usar @RestControllerAdvice.


21.14 Ejemplo de arquitectura limpia

1controller
2   recibe petición HTTP
3
4service
5   lógica de negocio
6
7repository
8   acceso a base de datos
9
10entity
11   modelo de datos
12
13dto
14   objetos de transferencia

21.15 Estructura final recomendada

1com.example.app
2
3config
4security
5exception
6
7user
8course
9payment
10notification

Cada módulo contiene:

1controller
2service
3repository
4entity
5dto
6mapper

Esto es lo más usado en proyectos profesionales.


  • Loading...