From 7ebefa4fd4a20ac0d67ee2ce491ace4336896c7e Mon Sep 17 00:00:00 2001 From: devfzn Date: Tue, 19 Sep 2023 01:18:50 -0300 Subject: [PATCH] Spring Boot 3: doc, test y prep. para impl.: Aula 3 --- 010_spring_boot/api_rest/api3/pom.xml | 8 +- .../api/controller/ConsultaController.java | 2 + .../voll/api/controller/MedicoController.java | 2 + .../api/controller/PacienteController.java | 2 + .../security/SecurityConfigurations.java | 4 +- .../springdoc/SpringDocConfigurations.java | 26 ++++++ 010_spring_boot/spring_boot_3.md | 93 +++++++++++++++++++ 7 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/springdoc/SpringDocConfigurations.java diff --git a/010_spring_boot/api_rest/api3/pom.xml b/010_spring_boot/api_rest/api3/pom.xml index cdec0b2..6fd7037 100644 --- a/010_spring_boot/api_rest/api3/pom.xml +++ b/010_spring_boot/api_rest/api3/pom.xml @@ -77,8 +77,14 @@ java-jwt 4.4.0 - + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.2.0 + + + diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java index 4b6b0c7..b936284 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/ConsultaController.java @@ -1,5 +1,6 @@ package med.voll.api.controller; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.validation.Valid; import med.voll.api.domain.consulta.AgendaDeConsultaService; import med.voll.api.domain.consulta.DatosAgendarConsulta; @@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.*; @Controller @ResponseBody @RequestMapping("/consultas") +@SecurityRequirement(name = "bearer-key") public class ConsultaController { @Autowired diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java index 6e1f110..cd5a9eb 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/MedicoController.java @@ -1,5 +1,6 @@ package med.voll.api.controller; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.transaction.Transactional; import jakarta.validation.Valid; import med.voll.api.domain.direccion.DatosDireccion; @@ -16,6 +17,7 @@ import java.net.URI; @RestController @RequestMapping("/medicos") +@SecurityRequirement(name = "bearer-key") public class MedicoController { @Autowired diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java index 3b978ee..4ee8f15 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/controller/PacienteController.java @@ -1,5 +1,6 @@ package med.voll.api.controller; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.transaction.Transactional; import jakarta.validation.Valid; import med.voll.api.domain.direccion.DatosDireccion; @@ -16,6 +17,7 @@ import java.net.URI; @RestController @RequestMapping("/pacientes") +@SecurityRequirement(name = "bearer-key") public class PacienteController { /* No es recomendable usar @Autowired a nivel de declaración pues genera diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/security/SecurityConfigurations.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/security/SecurityConfigurations.java index 2e20567..1affb5d 100644 --- a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/security/SecurityConfigurations.java +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/security/SecurityConfigurations.java @@ -26,8 +26,8 @@ public class SecurityConfigurations { return httpSecurity.csrf().disable().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and().authorizeHttpRequests() - .requestMatchers(HttpMethod.POST, "/login") - .permitAll() + .requestMatchers(HttpMethod.POST, "/login").permitAll() + .requestMatchers(HttpMethod.GET, "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**").permitAll() .anyRequest() .authenticated() .and() diff --git a/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/springdoc/SpringDocConfigurations.java b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/springdoc/SpringDocConfigurations.java new file mode 100644 index 0000000..10a9f9b --- /dev/null +++ b/010_spring_boot/api_rest/api3/src/main/java/med/voll/api/infra/springdoc/SpringDocConfigurations.java @@ -0,0 +1,26 @@ +package med.voll.api.infra.springdoc; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringDocConfigurations { + + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI().components(new Components() + .addSecuritySchemes( + "bearer-key", + new SecurityScheme().type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT"))); + } + + @Bean + public void message() { + System.out.println("bearer is working"); + } +} diff --git a/010_spring_boot/spring_boot_3.md b/010_spring_boot/spring_boot_3.md index 1e1085c..a6814f3 100644 --- a/010_spring_boot/spring_boot_3.md +++ b/010_spring_boot/spring_boot_3.md @@ -875,4 +875,97 @@ public ResponseEntity errorHandlerValidacionesDeNegocio(Exception e){ ## Documentación +[SpringDoc](https://springdoc.org/) + +La documentación es algo muy importante en un proyecto, especialmente si se trata +de una API Rest, ya que en este caso podemos tener varios clientes que necesiten +comunicarse con ella y necesiten documentación que les enseñe cómo realizar esta +comunicación de manera correcta. + +Durante mucho tiempo no existió un formato estándar para documentar una API Rest, +hasta que en 2010 surgió un proyecto conocido como ***Swagger***, cuyo objetivo +era ser una especificación **open source** para el diseño de APIs Rest. Después +de un tiempo, se desarrollaron algunas herramientas para ayudar a los +desarrolladores a implementar, visualizar y probar sus APIs, como ***Swagger UI, +Swagger Editor y Swagger Codegen***, lo que lo convirtió en un proyecto muy +popular y utilizado en todo el mundo. + +En 2015, Swagger fue comprado por la empresa ***SmartBear Software***, que donó +la parte de la especificación a la ***Fundación Linux***. A su vez, la +fundación renombró el proyecto a **OpenAPI**. Después de esto, se creó la +***OpenAPI Initiative***, una organización centrada en el desarrollo y la +evolución de la especificación OpenAPI de manera abierta y transparente. + +OpenAPI es actualmente la especificación más utilizada y también la principal +para documentar una API Rest. La documentación sigue un patrón que puede ser +descrito en formato **YAML** o **JSON**, lo que facilita la creación de +herramientas que puedan leer dichos archivos y automatizar la creación de +documentación, así como la generación de código para el consumo de una API. + +Más detalles en el sitio web oficial de la +[OpenAPI Initiative](https://www.openapis.org/). + +Dependencia en [pom.xml](./api_rest/api3/pom.xml) + +```xml + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.2.0 + +``` + +Permitir acceso a urls de **SpringDoc** sin token + +[SecurityConfigurations](./api_rest/api3/src/main/java/med/voll/api/infra/security/SecurityConfigurations.java) + +```java + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) + throws Exception { + ... + .requestMatchers(HttpMethod.POST, "/login").permitAll() + .requestMatchers(HttpMethod.GET, + "/swagger_ui.html", + "/swagger_ui/**", + "/v3/api-docs/**").permitAll() + ... +``` + +URLS: + +- `http://localhost:8080/v3/api-docs` +- `localhost:8080/swagger-ui.html` + +Nuevo *package* +[`api.infra.springdoc`](./api_rest/api3/src/main/java/med/voll/api/infra/springdoc/) +y clase +[SpringDocConfigurations](./api_rest/api3/src/main/java/med/voll/api/infra/springdoc/SpringDocConfigurations.java) + +```java +@Configuration +public class SpringDocConfigurations { + + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI().components(new Components() + .addSecuritySchemes( + "bearer-key", + new SecurityScheme().type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT"))); + } + + @Bean + public void message() { + System.out.println("bearer is working"); + } +} +``` + +Se agrega la anotacion `@SecurityRequirement(name = "bearer-key")` en las clases +*controller* para que el **Swagger** habilite la funcionalidad de autentificar +por token. + +---