Spring
Arquitectura en Capas de Spring Boot
[Link]/
├── 📁 config/ → Configuración
├── 📁 controller/ → Entrada (API REST)
├── 📁 dto/ → Objetos de transferencia
├── 📁 entity/ → Modelos de base de datos
├── 📁 exception/ → Manejo de errores
├── 📁 repository/ → Acceso a datos
├── 📁 scheduler/ → Tareas programadas
├── 📁 security/ → Autenticación y autorización
├── 📁 service/ → Lógica de negocio
└── 📄 MessageApplication → Clase principal
📚 Estructura de Spring Boot - Guía para Principiantes
Te explicaré cada carpeta y su función en tu proyecto
[Link]:
Arquitectura en Capas de Spring Boot
[Link]/
├── 📁 config/ → Configuración
├── 📁 controller/ → Entrada (API REST)
├── 📁 dto/ → Objetos de transferencia
├── 📁 entity/ → Modelos de base de datos
├── 📁 exception/ → Manejo de errores
├── 📁 repository/ → Acceso a datos
├── 📁 scheduler/ → Tareas programadas
├── 📁 security/ → Autenticación y autorización
├── 📁 service/ → Lógica de negocio
└── 📄 MessageApplication → Clase principal
📂 Explicación Detallada de Cada Carpeta
1. 📁 entity/ - Las Tablas de tu Base de Datos
¿Qué hace? Define la estructura de tus tablas en la base de datos.
java
// entity/[Link]
@Entity
@Table(name = "clients")
public class Client {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
💡 Analogía: Es como el plano arquitectónico de tu casa.
Define QUÉ campos tiene cada tabla
Spring automáticamente crea las tablas en la BD
Cada clase = 1 tabla
Cada atributo = 1 columna
2. 📁 repository/ - El Acceso a la Base de Datos
¿Qué hace? Se comunica directamente con la base de datos.
java
// repository/[Link]
@Repository
public interface ClientRepository extends JpaRepository<Client, Long>
{
// Spring crea automáticamente estos métodos:
// - findAll()
// - findById()
// - save()
// - delete()
// Puedes agregar consultas personalizadas:
List<Client> findByEmail(String email);
@Query("SELECT c FROM Client c WHERE [Link] = :status")
List<Client> findByStatus(@Param("status") String status);
💡 Analogía: Es el almacén donde guardas y buscas cosas.
Solo hace operaciones CRUD (Create, Read, Update, Delete)
NO tiene lógica de negocio
Es una interfaz (Spring hace la magia por ti)
3. 📁 dto/ - Objetos de Transferencia de Datos
¿Qué hace? Define QUÉ datos entran y salen de tu API.
java
// dto/[Link] (LO QUE RECIBE LA API)
@Data
public class ClientRequest {
@NotBlank(message = "El nombre es obligatorio")
private String firstName;
@NotBlank(message = "El apellido es obligatorio")
private String lastName;
@Email(message = "Email inválido")
private String email;
// Solo los datos necesarios para CREAR un cliente
// dto/[Link] (LO QUE DEVUELVE LA API)
@Data
@Builder
public class ClientResponse {
private Long id;
private String firstName;
private String lastName;
private String email;
private LocalDateTime createdAt;
// NO incluye datos sensibles como contraseñas
💡 Analogía: Es el formulario que llenas vs el ticket que recibes.
Request DTO: Lo que el usuario envía (formulario)
Response DTO: Lo que tu API devuelve (respuesta limpia)
¿Por qué no usar Entity?
o Seguridad: No expones toda la estructura de tu BD
o Flexibilidad: Puedes combinar datos de varias tablas
o Validación: Aplicas reglas específicas por caso de uso
4. 📁 service/ - La Lógica de Negocio (CEREBRO)
¿Qué hace? Contiene TODA la lógica de tu aplicación.
java
// service/[Link]
@Service
@RequiredArgsConstructor
public class ClientService {
private final ClientRepository clientRepository;
private final EmailService emailService;
public ClientResponse createClient(ClientRequest request) {
// 1. VALIDAR: ¿El email ya existe?
if ([Link]([Link]()).isPresent()) {
throw new IllegalStateException("El email ya está registrado");
// 2. CONVERTIR: DTO → Entity
Client client = [Link]()
.firstName([Link]())
.lastName([Link]())
.email([Link]())
.status("ACTIVE")
.createdAt([Link]())
.build();
// 3. GUARDAR en la base de datos
client = [Link](client);
// 4. LÓGICA DE NEGOCIO: Enviar email de bienvenida
[Link]([Link]());
// 5. CONVERTIR: Entity → DTO Response
return [Link]()
.id([Link]())
.firstName([Link]())
.lastName([Link]())
.email([Link]())
.createdAt([Link]())
.build();
💡 Analogía: Es el chef de cocina.
Recibe la orden (DTO Request)
Aplica las reglas del negocio (validaciones, cálculos)
Usa ingredientes (Repository)
Coordina con otros servicios (EmailService)
Devuelve el plato final (DTO Response)
Responsabilidades:
✅ Validaciones complejas
✅ Lógica de negocio
✅ Transacciones
✅ Orquestación de múltiples operaciones
❌ NO conoce nada de HTTP, JSON, requests
5. 📁 controller/ - La Puerta de Entrada (API REST)
¿Qué hace? Recibe las peticiones HTTP y las enruta.
java
// controller/[Link]
@RestController
@RequestMapping("/api/clients")
@RequiredArgsConstructor
public class ClientController {
private final ClientService clientService;
// POST /api/clients
@PostMapping
public ResponseEntity<ClientResponse> createClient(
@Valid @RequestBody ClientRequest request
){
ClientResponse response = [Link](request);
return
[Link]([Link]).body(response);
// GET /api/clients
@GetMapping
public ResponseEntity<Page<ClientResponse>> getAllClients(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
){
Pageable pageable = [Link](page, size);
Page<ClientResponse> clients =
[Link](pageable);
return [Link](clients);
}
// GET /api/clients/123
@GetMapping("/{id}")
public ResponseEntity<ClientResponse>
getClientById(@PathVariable Long id) {
ClientResponse client = [Link](id);
return [Link](client);
💡 Analogía: Es el mesero del restaurante.
Recibe pedidos (HTTP Requests)
Pasa la orden al chef (Service)
Devuelve el plato al cliente (HTTP Response)
NO cocina (no tiene lógica)
Responsabilidades:
✅ Definir rutas (endpoints)
✅ Validar formato de entrada (@Valid)
✅ Manejar parámetros (query params, path variables)
✅ Devolver códigos HTTP correctos (200, 201, 404, 500)
❌ NO debe tener lógica de negocio
6. 📁 exception/ - Manejo de Errores
¿Qué hace? Maneja todos los errores de forma centralizada.
java
// exception/[Link]
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
// exception/[Link]
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorResponse>
handleNotFound(ResourceNotFoundException ex) {
ErrorResponse error = [Link]()
.status(404)
.message([Link]())
.timestamp([Link]())
.build();
return
[Link](HttpStatus.NOT_FOUND).body(error);
@ExceptionHandler([Link])
public ResponseEntity<ErrorResponse>
handleIllegalState(IllegalStateException ex) {
ErrorResponse error = [Link]()
.status(400)
.message([Link]())
.timestamp([Link]())
.build();
return [Link]().body(error);
}
💡 Analogía: Es el departamento de atención al cliente.
Captura todos los errores
Los convierte en respuestas amigables
Evita que el sistema explote
7. 📁 config/ - Configuración Global
¿Qué hace? Configura herramientas y comportamientos del sistema.
java
// config/[Link]
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
// Configurar qué rutas requieren autenticación
// config/[Link]
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
// Permitir requests desde tu frontend
8. 📁 security/ - Autenticación y Autorización
¿Qué hace? Controla quién puede acceder y qué puede hacer.
java
// security/[Link]
public class JwtTokenProvider {
public String generateToken(User user) {
// Crear token JWT
public boolean validateToken(String token) {
// Validar token
// security/[Link]
public class JwtAuthenticationFilter extends OncePerRequestFilter {
// Interceptar requests y validar tokens
9. 📁 scheduler/ - Tareas Automáticas
¿Qué hace? Ejecuta código en intervalos de tiempo.
java
// scheduler/[Link]
@Service
public class TaskSchedulerService {
@Scheduled(fixedRate = 60000) // Cada minuto
public void checkPendingTasks() {
// Buscar tareas pendientes y ejecutarlas
```
---
## 🔄 **Flujo Completo de una Petición**
```
1. Usuario → Frontend envía: POST /api/clients
JSON: { "firstName": "Juan", "lastName": "Pérez", "email":
"juan@[Link]" }
2. ⬇️CONTROLLER recibe el request
[Link]()
- Valida formato JSON
- Convierte JSON → ClientRequest DTO
3. ⬇️SERVICE procesa lógica
[Link]()
- Valida que el email no exista
- Crea Entity Client
- Guarda en BD vía Repository
- Envía email de bienvenida
- Convierte Entity → ClientResponse DTO
4. ⬇️REPOSITORY guarda en BD
[Link](client)
- Ejecuta: INSERT INTO clients ...
5. ⬆️SERVICE devuelve respuesta
ClientResponse con datos del cliente creado
6. ⬆️CONTROLLER devuelve HTTP 201
JSON: { "id": 123, "firstName": "Juan", ... }
7. ⬆️Frontend recibe respuesta
📋 Resumen Rápido
Capa Rol Analogía
Controll Recibe peticiones
Mesero
er HTTP
Service Lógica de negocio Chef
Reposito
Acceso a BD Almacén
ry
Plano
Entity Estructura de tablas
arquitectónico
Formato de
DTO Formulario/Ticket
entrada/salida
Exceptio
Manejo de errores Atención al cliente
n
Config Configuración global Gerencia
Seguridad del
Security Autenticación
edificio
Schedul Alarmas
Tareas automáticas
er programadas
✨ Principios Clave
1. Separación de Responsabilidades: Cada capa hace UNA
cosa
2. Controller NO tiene lógica → Solo enruta
3. Service tiene TODA la lógica → Es el cerebro
4. Repository SOLO accede a BD → No hace cálculos
5. Entity = BD, DTO = API → Nunca mezcles