AdBlock Detected

It looks like you're using an ad-blocker!

Our team work realy hard to produce quality content on this website and we noticed you have ad-blocking enabled. Advertisements and advertising enable us to continue working and provide high-quality content.

OpenAPI and swagger UI in Quarkus

In this article, we will see how we can expose our services in Quarkus using OpenAPI with the help of the Swagger UI interface.

Undoubtedly, Quarkus is one of the most promising frameworks due to its easy integration with Kubernetes, for example, and its fast startup times. The latter is a crucial feature when working with applications in the cloud because it enables rapid scaling of Pods.

What is OpenAPI?

OpenAPI or OAS is a language-agnostic standard that defines a specification allowing us to comprehensively expose our API with a human-friendly interface. Using OpenAPI helps us generate documentation and easily understand the services we are exposing. To visualize and interact with this documentation, we can make use of Swagger UI, which provides a graphical interface displaying the endpoints and documentation of our application.

There are different ways to work with API generation, such as API First or Code First.

Creating a Quarkus Project with OpenAPI

Project Generation with Maven

To begin, let’s generate our Quarkus project using the generator provided by Quarkus and Maven:

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"

With this Maven command, we have generated the structure of our project, adding OpenAPI and an endpoint /cars.

Generating the REST Project with Quarkus

Once we have generated the structure with Maven, let’s create the resource (controller) with Spring and the object representing our resource.

Now, we define the CarResource class, which was generated by 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;
    }
}

Next, let’s create the Car object since we have updated the API (CarResource). The following class represents the Car object:

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;
  }



}

As we have updated the API, we need to update the test to ensure that all changes we made are properly verified:

@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"));
    }
}

Exposing the OpenAPI Specification

Next, we will expose our OpenAPI specification in version 3. To do this, we first need to add the following dependency:

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

This dependency, among other things, integrates Swagger UI to visualize our specification graphically.

Now, let’s start our application using Maven:

mvn compile quarkus:dev

If it is your first time using Quarkus, you will notice its incredible startup times.

To view our OpenAPI specification, navigate to http://localhost:8080/q/openapi. This endpoint will display the specification in plain text. If you are familiar with the Swagger interface and want to view the specification interactively, use the following endpoint: http://localhost:8080/q/swagger-ui.

If you wish to change the OpenAPI and Swagger endpoints, you can do so in your application.properties:

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

With the above properties, the specification will be accessible at http://localhost:8080/swagger, and the interface will be available at http://localhost:8080/swagger-ui.

Conclusion

Using OpenAPI to expose our API is very helpful to view our specification. In this article, “OpenAPI and Swagger UI in Quarkus,” we have seen how to generate our application and view the specification using Swagger with its graphical interface or in plain text.

If you want to see the complete example, you can find it on our GitHub by clicking here.

Leave a Reply

Your email address will not be published. Required fields are marked *