OpenAPI y swagger UI en Quarkus

swagger with quarkus

swagger with quarkus


En este artículo vamos a ver como podemos exponer nuestros servicios en Quarkus a través de OpenAPI haciendo uso de la interfaz que swagger UI nos proporciona.

Sin duda Quarkus es uno de los frameworks más prometedores, debido a su fácil integración con Kubernetes por ejemplo, y a su gran velocidad en los tiempos de arranque. Ya que esta última es una de las características más necesarias cuando trabajamos con aplicaciones en un cloud, debido a que si queremos escalar por ejemplo, un Pod conseguiremos que este se levante a una gran velocidad.

¿Qué es OpenAPI?

OpenAPI o OAS, es un estándar que nos define una especificación, que es totalmente agnóstica al lenguaje. Este estándar nos va a permitir exponer nuestra API através de una interfaz de una manera comprensive para los humanos.

El uso de OpenAPI nos va a ayudar y a permitir generar documentación y entender de una manera fácil y dinámica los servicios que estamos exponiendo. Para facilitar este trabajo y poder ver esa documentación en vivo y poder además interactúar con ella, podemos hacer uso de Swagger UI, la cual nos proporciona una interfaz gráfica que nos muestra los endpoints y documentación de nuestra aplicación.

Dentro de la generación de nuestra API, tenemos diferentes formas de trabajo como por ejemplo API First o Code First.

Crear proyecto Quarkus con OpenAPI

Generación con maven

Para empezar vamos a generar nuestro proyecto Quarkus haciendo uso del generador que Quarkus y maven nos proporcionan:

mvn io.quarkus:quarkus-maven-plugin:1.11.3.Final:create     -DprojectGroupId=com.refactorizando   -DprojectArtifactId=example-openapi-swaggerui -DclassName="com.refactorizando.example.openapi.swaggerui.CarResource" -Dpath="/cars"     -Dextensions="resteasy,resteasy-jackson"

Con este comando maven hemos generado la estructura de nuestro proyecto añadiendo OpenAPI y un endpoint /cars.

Generarción de proyecto REST con Quarkus

Una vez hemos generado la estructura con maven, vamos a generar el resource, o controller con Spring, y el objeto que representa nuestro resource.

A continuación vamos a representar el objeto CarResource, el cual fue generado por maven..

@Path("/cars")
public class CarResource {


    private Set<Car> cars = Collections.newSetFromMap(Collections.synchronizedMap(new LinkedHashMap<>()));

    public CarResource() {
        cars.add(new Car(1L, "Ford", "Mustang", "Black"));
        cars.add(new Car(2L, "Renault", "Megane", "Yellow"));
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Set<Car> list() {
        return cars;
    }

    @POST
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.TEXT_PLAIN)
    public Set<Car> add(Car car) {
        cars.add(car);
        return cars;
    }

    @DELETE
    public Set<Car> delete(Car car) {
        cars.removeIf(existingCar -> existingCar.getId().equals(car.getId()));
        return cars;
    }
}

Una vez definido la clase CarResource vamos a crear el objeto car.

public class Car {

  private String name;

  private String model;

  private String color;

  public Car(String name, String model, String color) {
    this.name = name;
    this.model = model;
    this.color = color;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getModel() {
    return model;
  }

  public void setModel(String model) {
    this.model = model;
  }

  public String getColor() {
    return color;
  }

  public void setColor(String color) {
    this.color = color;
  }



}

Y debido a que hemos actualizado el API (carResource), vamos a actualizar el test para poder verificar correctamente que todo cambio que realizamos es correctamente verificado.

@QuarkusTest
public class CarResourceTest {

    @Test
    public void testList() {
        given()
            .when().get("/cars")
            .then()
            .statusCode(200)
            .body("$.size()", is(2),
                "brand", containsInAnyOrder("Ford", "Renault"));
    }

    @Test
    public void testAdd() {
    given()
        .body(
            "{\n"
                + "  \"brand\": \"Ford\",\n"
                + "  \"color\": \"Black\",\n"
                + "  \"id\": 0,\n"
                + "  \"model\": \"Mustang\"\n"
                + "}")
        .header("Content-Type", MediaType.APPLICATION_JSON)
        .when()
        .post("/cars")
        .then()
        .statusCode(200)
        .body(
            "$.size()",
            is(3),
            "brand",
            containsInAnyOrder("Ford", "Renault", "Ford"),
            "model",
            containsInAnyOrder("Mustang", "Megane", "Mustang"));

        given()
            .body(
                "{\n"
                    + "  \"brand\": \"Ford\",\n"
                    + "  \"color\": \"Black\",\n"
                    + "  \"id\": 0,\n"
                    + "  \"model\": \"Mustang\"\n"
                    + "}")
            .header("Content-Type", MediaType.APPLICATION_JSON)
            .when()
            .delete("/cars")
            .then()
            .statusCode(200)
            .body(
                "$.size()",
                is(2),
                "brand",
                containsInAnyOrder("Ford", "Renault"),
                "model",
                containsInAnyOrder("Mustang", "Megane"));
    }
}

Exponer la especificación de OpenApi

A continuación vamos a exponer nuestra especificación de OpenApi en versión 3, para ello primero tenemos que añadir la siguiente dependencia.

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>

Esta dependencia, entre otras cosas, integra swagger-ui para poder visualizar nuestra espeficación de forma gráfica.

Arrancamos nuestra aplicación haciendo uso de maven:

mvn compile quarkus:dev

Si es la primera vez que usas quarkus habrás observado que sus tiempos de arranque son increíbles.

Y vamos al siguiente endpoint para ver nuestra especificación, http://localhost:8080/q/openapi. Con este endpoint veremos la especificación en texto plano, pero si ya hemos trabajado y estamos familiarizados con la interfaz de swagger, lo mejor será ejecutar el siguiente endpoint, http://localhost:8080/q/swagger-ui.

Si quieres cambiar el endpoint de openapi y el de swagger, se puede hacer de la siguiente manera en tu application.properties

quarkus.swagger-ui.path=/swagger-ui
quarkus.smallrye-openapi.path=/swagger

Con las propiedates anteriores hemos cambiado los endpoint y ahora la especificación estará accesible en el endpoint http://localhost:8080/swagger y la interfaz estará disponible en el endpoint http://localhost:8080/swagger-ui

Conclusión

Hacer uso de OpenApi para exponer nuestra API es de gran ayuda para ver nuestra especificación. En este artículo, OpenAPI y swagger UI en Quarkus, hemos visto como podemos generar nuestra aplicación y poder ver nuestra especificación haciendo uso de swagger y su interfaz o verla por pantalla en texto.

Si quieres ver el ejemplo completo puedes verlo en nuestro Github pulsando aquí.

Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com y te ayudaremos encantados!


No te olvides de seguirnos en nuestras redes sociales Facebook o Twitter para estar actualizado.


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *