From 41f062fdd7b42c75e4be7ea1dc969957d695fc86 Mon Sep 17 00:00:00 2001 From: devfzn Date: Fri, 8 Sep 2023 16:28:22 -0300 Subject: [PATCH] Desarrollo API Rest: Aula 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mapeo de solicitudes POST en clase Controller - solicitudes POST a la API usando Insomnia - datos a la API en formato JSON - anotación @RequestBody para recibir datos del cuerpo de la solicitud en un parámetro en el Controller - patrón DTO con Java Records, representando datos recibidos en un POST. --- .../voll/api/controller/MedicoController.java | 15 ++ .../voll/api/direccion/DatosDireccion.java | 4 + .../voll/api/medico/DatosRegistroMedico.java | 8 + .../med/voll/api/medico/Especialidad.java | 8 + .../imgs/spring_boot_cors_error.png | Bin 0 -> 19578 bytes 010_spring_boot/spring_boot_1.md | 219 +++++++++++++++++- README.md | 1 + 7 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java create mode 100644 010_spring_boot/api_rest/api/src/main/java/med/voll/api/direccion/DatosDireccion.java create mode 100644 010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/DatosRegistroMedico.java create mode 100644 010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Especialidad.java create mode 100644 010_spring_boot/imgs/spring_boot_cors_error.png diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java new file mode 100644 index 0000000..69bb17a --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java @@ -0,0 +1,15 @@ +package med.voll.api.controller; + +import med.voll.api.medico.DatosRegistroMedico; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/medicos") +public class MedicoController { + + @PostMapping + public void registrarMedico(@RequestBody DatosRegistroMedico datosRegistroMedico) { + System.out.println(datosRegistroMedico); + } + +} diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/direccion/DatosDireccion.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/direccion/DatosDireccion.java new file mode 100644 index 0000000..892015c --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/direccion/DatosDireccion.java @@ -0,0 +1,4 @@ +package med.voll.api.direccion; + +public record DatosDireccion(String calle, String distrito, String cuidad, String numero, String complemento) { +} diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/DatosRegistroMedico.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/DatosRegistroMedico.java new file mode 100644 index 0000000..0c22109 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/DatosRegistroMedico.java @@ -0,0 +1,8 @@ +package med.voll.api.medico; + +import med.voll.api.direccion.DatosDireccion; + +public record DatosRegistroMedico(String nombre, String email, String documento, + Especialidad especialidad, DatosDireccion direccion) { + +} diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Especialidad.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Especialidad.java new file mode 100644 index 0000000..752c4b6 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Especialidad.java @@ -0,0 +1,8 @@ +package med.voll.api.medico; + +public enum Especialidad { + ORTOPEDIA, + CARDIOLOGIA, + GINECOLOGIA, + PEDIATRIA +} diff --git a/010_spring_boot/imgs/spring_boot_cors_error.png b/010_spring_boot/imgs/spring_boot_cors_error.png new file mode 100644 index 0000000000000000000000000000000000000000..4d9a5fa32ea5cc98e9dfe3355466358d7c79ceba GIT binary patch literal 19578 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 Z*Q&HjAanjT*e`6yC3{D7x$W)Pe*wDE)mZ=l literal 0 HcmV?d00001 diff --git a/010_spring_boot/spring_boot_1.md b/010_spring_boot/spring_boot_1.md index e9c3446..3c5c9e0 100644 --- a/010_spring_boot/spring_boot_1.md +++ b/010_spring_boot/spring_boot_1.md @@ -66,7 +66,6 @@ El lanzamiento de Spring Boot fue un hito para el desarrollo de aplicaciones Java, ya que hizo más simple y ágil esta tarea, facilitando mucho la vida de las personas que utilizan el lenguaje Java para desarrollar sus aplicaciones. - La versión 3 de Spring Boot se lanzó en noviembre de 2022 y algunas de sus nuevas características principales son: @@ -110,3 +109,221 @@ api └── pom.xml ``` + +### Utilizando Insomnia + +AppImage de [Insomnia](https://github.com/Kong/insomnia/releases/) para probar API + +Test post a `http://127.0.0.1:8080/medicos`, **json** + +```json +{ + "nombre": "Rodrigo Lopez", + "email": "rodrigo.lopez@voll.med", + "documento": "123456", + "especialidad": "ortopedia", + "direccion": { + "calle": "calle 1", + "distrito": "distrito 1", + "ciudad": "Lima", + "numero": "1", + "complemento": "a" + } +} +``` + +#### JSON + +**JSON** (JavaScript Object Notation) es un formato utilizado para representar +información, al igual que **XML** y **CSV**. + +Una API necesita recibir y devolver información en algún formato que represente +los recursos que administra. **JSON** es uno de estos posibles formatos, popular +por su ligereza, sencillez, facil lectura (humana y máquina), así como por su +soporte para diferentes lenguajes de programación. + +Representación de información en formato **XML** + +```xml + + Mochila + 89.90 + Mochila para notebooks de hasta 17 pulgadas + +``` + +Representación en formato **JSON** + +```json +{ + “nombre” : “Mochila”, + “precio” : 89.90, + “descripcion” : “Mochila para notebooks de hasta 17 pulgadas” +} +``` + +Observe cómo el formato JSON es mucho más compacto y legible. Precisamente por eso, se ha convertido en el formato universal utilizado en la comunicación de aplicaciones, especialmente en el caso de las API REST. + +Más detalles sobre [JSON](https://www.json.org/json-es.html) + +#### CORS + +Al desarrollar una API y se busca que sus recursos estén disponibles para +cualquier ***cliente HTTP***. + +**CORS** (Cross-Origin Resource Sharing) o “Intercambio de recursos con +diferentes orígenes”. Es común tener errores CORS al consumir y poner a +disposición una API. + +![img](./imgs/spring_boot_cors_error.png) + +**CORS** es un mecanismo utilizado para agregar encabezados HTTP que indica a +los navegadores permitir que una aplicación web se ejecute en un origen y acceda +a los recursos desde un origen diferente. Este tipo de acción se denomina +***cross-origin HTTP request***. +En la práctica, les informa a los navegadores si se puede acceder o no a un +recurso en particular. + +Entendiendo los errores + +***`Same-origin policy`*** +Por defecto, una aplicación Front-end, escrita en JavaScript, solo puede acceder +a los recursos ubicados en el mismo origen de la solicitud. Esto sucede debido +a la política del mismo origen (*same-origin policy*), que es un mecanismo de +seguridad de los navegadores que restringe la forma en que un documento o script +de un origen interactúa con los recursos de otro. +Esta política tiene como objetivo detener los ataques maliciosos. + +Dos URL comparten el mismo origen si el **protocolo**, el **puerto** (si se +especifica) y el **host** son los mismos. Comparemos posibles variaciones +considerando la URL `https://cursos.alura.com.br/category/programacao`: + +| URL | Resultado | Motivo | +| - | - | - | +| `https://cursos.alura.com.br/category/front-end` | Mismo origen | Solo camino diferente | +| `http://cursos.alura.com.br/category/programacao` |Error de CORS | Protocolo diferente (http) | +| `https://faculdade.alura.com.br:80/category/programacao` | Error de CORS | Host diferente | + +#### ¿Como consumir una API con una URL diferente sin tener problemas CORS? + +Por ejemplo, si se quiere consumir una API que se ejecuta en el puerto `8000` desde +una aplicación React corriendo en el puerto `3000`. + +Al enviar una solicitud a una API de origen diferente, la API debe devolver un +header llamado `Access-Control-Allow-Origin`. Dentro de esta, es ella es necesario +informar los diferentes orígenes que serán permitidas de consumir la API, en +este caso: `Access-Control-Allow-Origin: http://localhost:3000`. + +Para permitir el acceso desde cualquier origen se utiliza el símbolo `*`: +`Access-Control-Allow-Origin: *`. Esta es una medida **no recomendada**, ya que +permite que fuentes desconocidas accedan al servidor, a menos que sea intencional, +como en el caso de una API pública. + +**¿Cómo hacer esto en Spring Boot correctamente?** + +#### Habilitando diferentes orígenes en Spring Boot + +Configurar el **CORS** para permitir que un origen específico consuma la API, +creando una clase de configuración como la sgte. + +```java +@Configuration +public class CorsConfiguration implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins("http://localhost:3000") + .allowedMethods("GET", "POST", "PUT", "DELETE", + "OPTIONS", "HEAD", "TRACE", "CONNECT"); + } +} +``` + +`http://localhost:3000` sería la dirección de la aplicación Front-end y +`.allowedMethods` los métodos que se permitirán ejecutar. Con esto se podrá +consumir la API sin problemas desde una aplicación front-end. + +#### Restricciones o validaciones + +|| Médico || +| :- | :- | :- | +| Nombre | Solo letras | No puede llegar vacío | +| Especialidad | Ortopedia, Ginecología,
Cardiología, Pediatria | No puede llegar vacío | +| Documento | Solo números | No puede llegar vacío | +| Email | Formato de email | No puede llegar vacío | +| Teléfono | Solo números | No puede llegar vacío | + +|| Dirección || +| :- | :- | :- | +| Calle | Letras y números | No puede llegar vacío | +| Número | Solo números | No puede llegar vacío | +| Complemento | Letras y números | | +| Cuidad | Letras y números | No puede llegar vacío | + +### Java Record + +Lanzado oficialmente en Java 16, pero disponible experimentalmente desde Java 14. +**Record** es un recurso que ***permite representar una clase inmutable, que +contiene solo atributos, constructor y métodos de lectura***, de una manera muy +simple y ágil. + +Este tipo de clase encaja perfectamente para representar **clases DTO**, ya que +su objetivo es únicamente representar datos que serán recibidos o devueltos por +la API, sin ningún tipo de comportamiento. + +Para crear una clase DTO inmutable, sin la utilización de Record, era necesario +escribir mucho código. El sgte. es un ejemplo de una clase DTO que representa +un teléfono: + +```java +public final class Telefono { + + private final String ddd; + private final String numero; + + public Telefono(String ddd, String numero) { + this.ddd = ddd; + this.numero = numero; + } + + @Override + public int hashCode() { + return Objects.hash(ddd, numero); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (!(obj instanceof Telefono)) { + return false; + } else { + Telefono other = (Telefono) obj; + return Objects.equals(ddd, other.ddd) + && Objects.equals(numero, other.numero); + } + } + + public String getDdd() { + return this.ddd; + } + + public String getNumero() { + return this.numero; + } +} +``` + +Con **Record** todo ese código se puede resumir en una sola línea: + +```java +public record Telefono(String ddd, String numero){} +``` + +Internamente, Java transforma este registro en una clase inmutable, muy similar +al código que se muestra arriba. + +Documentación Java +[record](https://docs.oracle.com/en/java/javase/17/language/records.html) + diff --git a/README.md b/README.md index 654f977..90c7c4f 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,4 @@ primoridiales en programación con Javascript - [JDBC](./010_spring_boot/jdbc.md) - [Persistencia con JPA - Hibernate](./010_spring_boot/jpa_persistencia_hibernate.md) - [JPA consultas avanzadas, rendimiento y modelos complejos](./010_spring_boot/jpa_avanzado.md) + - [Desarrollo API Rest](./010_spring_boot/spring_boot_1.md)