Guia Springasd
Guia Springasd
Guia Springasd
md 2024-10-13
Una vez instalado PostgreSQL sigue el tutorial (minuto 9:28 a 12:28) para agregar una nueva data source en intellij y crear la
base de datos.
jdbc:postgresql://localhost:
JDBC_DB_URL jdbc:postgresql://localhost:5432/tfi_ar_db
{puerto}/{nombre_db}
La entidad debe ser creada en el paquete model. Esta entidad representa una tabla en la base de datos y se define
utilizando las anotaciones de JPA.
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "employee")
@SQLDelete(sql = "UPDATE employee SET deleted = true WHERE id = ?")
@Where(clause = "deleted = false")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(unique = true)
private String dni;
private String name;
1/5
guiaSpring.md 2024-10-13
@Column(name = "birth_date")
private LocalDate birthDate;
@Column(unique = true)
private String email;
private String phone;
@Column(name = "start_date", updatable = false)
private LocalDate startDate;
@Column(name = "end_date")
private LocalDate endDate;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "created_by", nullable = false)
private User createdBy;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "updated_by")
private User updatedBy;
private boolean deleted;
}
Explicación
@Entity: Indica que la clase es una entidad JPA y corresponde a una tabla en la base de datos.
@Table: Define el nombre de la tabla en la base de datos.
@Id y @GeneratedValue: Indican que el campo id es la clave primaria y su valor se generará automáticamente.
@Column: Define las propiedades de la columna en la base de datos, como unique y name.
@OneToOne y @ManyToOne: Definen relaciones entre entidades. Aquí, Employee tiene una relación con User para
user, createdBy, y updatedBy.
@SQLDelete y @Where: Permiten realizar un "soft delete" de la entidad, donde en lugar de eliminar la fila de la base
de datos, se marca como eliminada.
En el paquete repository, crea la interfaz para el repositorio de la entidad. Aquí, puedes agregar métodos personalizados
que no estén disponibles en JpaRepository.
Explicación
JpaRepository: Proporciona un conjunto de métodos para realizar operaciones CRUD y consultas en la base de
datos.
findByEmail y findByUserId: Métodos personalizados que te permiten buscar un empleado por su correo
electrónico o ID de usuario. Estos métodos facilitan la validación y verificación en el servicio.
Los DTOs (Data Transfer Objects) son utilizados para la comunicación entre la API y el cliente. Los nombres de los campos en
la clase DTO deben seguir la convención snake_case, ya que es el estándar en el formato JSON.
2/5
guiaSpring.md 2024-10-13
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EmployeeRequest {
private String dni;
private String name;
@JsonProperty("birth_date")
private LocalDate birthDate;
private String email;
private String phone;
@JsonProperty("start_date")
private LocalDate startDate;
@JsonProperty("user_id")
private Integer userId;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EmployeeResponse {
private String dni;
private String name;
@JsonProperty("birth_date")
private LocalDate birthDate;
private String email;
private String phone;
@JsonProperty("start_date")
private LocalDate startDate;
@JsonProperty("user_id")
private Integer userId;
}
@JsonProperty: Utilizada para mapear el nombre del campo en el JSON a un nombre diferente en el objeto Java. Esto es
útil para mantener las convenciones de nombres correctas entre el cliente y el servidor.
4. Creamos el servicio
El servicio contiene la lógica de negocio y es responsable de interactuar con el repositorio para realizar operaciones de
creación, actualización y eliminación.
@Service
@RequiredArgsConstructor
public class EmployeeService {
private final EmployeeRepository employeeRepository;
private final UserRepository userRepository;
private final AuthenticationService authenticationService;
if (employeeRepository.findByUserId(request.getUserId()).isPresent()) {
throw new UserAlreadyInUseException("User already in use");
3/5
guiaSpring.md 2024-10-13
User creatorUser =
userRepository.findById(authenticationService.getUserIdFromToken())
.orElseThrow(() -> new UserNotFoundException("User not found"));
employeeRepository.save(employee);
return EmployeeResponse.builder()
.dni(employee.getDni())
.name(employee.getName())
.birthDate(employee.getBirthDate())
.email(employee.getEmail())
.phone(employee.getPhone())
.userId(employee.getUser().getId())
.build();
}
}
Explicación
@Service: Indica que esta clase es un servicio de Spring y se encargará de la lógica de negocio.
@RequiredArgsConstructor: Genera un constructor que inyecta las dependencias requeridas.
createEmployee: Método para crear un nuevo empleado. Realiza las siguientes verificaciones:
Comprueba si el correo ya está en uso.
Verifica si el userId ya está asociado a otro empleado.
Busca el User asociado y el creador del empleado utilizando el servicio de autenticación.
Si todo es válido, crea un nuevo Employee y lo guarda en el repositorio.
Excepciones personalizadas: Se lanzan si hay problemas con los datos de entrada. Estas excepciones deben ser
definidas en el paquete exception.
5. Creamos el controlador
El controlador es responsable de manejar las solicitudes HTTP y mapearlas a los métodos del servicio correspondiente.
@RestController
@RequestMapping("/api/v1/employees")
@RequiredArgsConstructor
@PreAuthorize("hasRole('ADMIN') or hasRole('HR_MODULE_USER')")
public class EmployeeController {
private final EmployeeService employeeService;
@PostMapping
4/5
guiaSpring.md 2024-10-13
Explicación
@RestController: Indica que esta clase es un controlador que maneja solicitudes REST.
@RequestMapping: Define la ruta base para las solicitudes a este controlador.
@PreAuthorize: Define restricciones de acceso, asegurando que solo los usuarios con los roles apropiados puedan
acceder a este método.
create: Método que maneja las solicitudes POST para crear empleados. Utiliza el DTO EmployeeRequest para recibir
los datos y llama al servicio correspondiente.
Finalmente, para probar la nueva feature, utilizaremos Postman. Es esencial agregar el token de acceso para autorizar la
solicitud.
Configura Postman:
Método: POST
URL: http://localhost:8080/api/v1/employees
Authorization: Selecciona Bearer Token e ingresa tu token de acceso.
Body: Selecciona raw y luego JSON. Inserta el siguiente JSON en el cuerpo de la solicitud:
{
"dni": "12345678",
"name": "Juan Pérez",
"birth_date": "1990-01-01",
"email": "[email protected]",
"phone": "+1234567890",
"start_date": "2024-10-12",
"user_id": 1
}
5/5