Guia Springasd

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 5

guiaSpring.

md 2024-10-13

Guía Spring Boot


Configuración de la Base de Datos PostgreSQL
1. Descargar e instalar PostgreSQL

Descarga e instala PostgreSQL desde https://www.postgresql.org/download/.


Durante la instalación, asegúrate de configurar un usuario y contraseña para la base de datos. Esto será necesario
para conectarte desde la aplicación.

2. Crear una nueva base de datos

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.

Configurar las variables de entorno


Siguiente el tutorial agrega las siguientes variables de entorno:

ENV VAR Value Ejemplo

jdbc:postgresql://localhost:
JDBC_DB_URL jdbc:postgresql://localhost:5432/tfi_ar_db
{puerto}/{nombre_db}

DB_USERNAME {usuario_db} postgres

DB_PASSWORD {contraseña_db} 1234

Puedes generar una key


JWT_KEY con el comando openssl 93f10dbfba7af357b2b9cc0d9a881e339e1e3ea1162c8f01dfaf6d3641ad1ce2
rand -hex 32

Paso a paso para desarrollar una feature


Nota: Durante el desarrollo se debería de usar el git workflow del otro pdf

1. Crear el modelo de la entidad sobre la cual estoy trabajando

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.

2. Crear el repositorio de la entidad

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.

public interface EmployeeRepository extends JpaRepository<Employee, Integer> {


Optional<Employee> findByEmail(String email);
Optional<Employee> findByUserId(Integer userId);
}

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.

3. Creamos los DTOs de petición y respuesta

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;

public EmployeeResponse createEmployee(EmployeeRequest request) throws


EmailAlreadyInUseException, UserAlreadyInUseException, UserNotFoundException {
if (employeeRepository.findByEmail(request.getEmail()).isPresent()) {
throw new EmailAlreadyInUseException("Email already in use");
}

if (employeeRepository.findByUserId(request.getUserId()).isPresent()) {
throw new UserAlreadyInUseException("User already in use");

3/5
guiaSpring.md 2024-10-13

User employeeUser = userRepository.findById(request.getUserId())


.orElseThrow(() -> new UserNotFoundException("User not found"));

User creatorUser =
userRepository.findById(authenticationService.getUserIdFromToken())
.orElseThrow(() -> new UserNotFoundException("User not found"));

var employee = Employee.builder()


.dni(request.getDni())
.name(request.getName())
.birthDate(request.getBirthDate())
.email(request.getEmail())
.phone(request.getPhone())
.user(employeeUser)
.startDate(request.getStartDate())
.createdBy(creatorUser)
.build();

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

public EmployeeResponse create(@RequestBody EmployeeRequest request) throws


UserNotFoundException, UserAlreadyInUseException, EmailAlreadyInUseException {
return employeeService.create(request);
}
}

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.

6. Testear con Postman

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

También podría gustarte