REST-API-Roundtrip with SpringDoc and OpenAPI Generator

cloud @viadee
Feb 16 · 10 min read

It is a no-brainer to provide JSON REST endpoints in a Spring Boot application, just like many state-of-the-art frameworks. Just include the Spring Boot Web Starter as a dependency, define a class annotated with @RestController, and implement at least one method annotated with @RequestMapping (or a specific annotation) as a handler for HTTP requests.

However, in a full API lifecycle, there is more to be done. In this article, we introduce an automated tool chain that helps professionalize Spring Boot REST API development and automates a lot of manual efforts.

Code-First But with a specification

The figure below illustrates that with a code-first approach, first, a Spring Boot application is set up (1), then, REST endpoints and implicitly an API is created (2). Sometimes an API documentation is written, for example, according to the OpenAPI standard (3) and occasionally an API client is created as well (4).

Example: User API

The API allows to create, update, and query users. For this purpose, REST operations are provided in an HTTP compliant manner using GET, POST, PUT or DELETE.

While relevant code snippets are included below, the code for the complete case is publicly available on GitHub: https://github.com/viadee/api-roundtrip-spring-boot

API-Roundtrip — The Full-Service-Package

  • REST-API
    The API itself
  • API-Documentation
    An API documentation as an OpenAPI specification
  • API-Client
    A client for using the API that can be easily integrated in an application
  • Integration Tests
    That automatically test the functionality of the API after deployment, for instance, in a test environment

Status Quo

Nowadays, tools such as Postman, SOAP UI or REST Assured are often used for integration tests. They all have allowances for sending JSON requests to a REST API.

Because of a necessity of creating and maintaining JSON requests as well as checks for the resulting JSON responses, this often results in high manual effort compared to the original API development.

Often, even a small adjustment in the Spring boot application involves a high manual and often annoying effort considering the overall package.

Automation thanks to SpringDoc and OpenApi Generator

The latter is achieved when integration tests are implemented in Java, like the Spring Boot application itself.

The following illustration provides an overview of the tool chain we describe in this article.

First, an OpenAPI documentation is generated using SpringDoc based on the Spring Boot REST API implementation. In the second step, appropriate client code and integration test code is generated with OpenAPI Generator facilitating the API documentation.

Of course, implementing the actual test logic still requires manual effort.

In detail, the tool chain consists of the following components:

  • Spring Boot
    Implements the REST-API (1)
  • SpringDoc
    Generates the API documentation as an OpenAPI specification and a Swagger UI facilitating the Spring Boot application infrastructure. (2)
  • OpenAPI
    Generates the code for API client(s) and integration tests from the OpenAPI specification generated by SpringDoc. (3)
  • Maven
    Orchestrates and executes the tools respectively with their concurring plugins. Of course, a similar chain can be built with Gradle.
  • Integration Tests
    The integration test execution depends on the concrete environment. In this article, we provide an example, where integration tests are triggered with Maven within a deployment pipeline after the deployment itself. (4)

API-Roundtrip — The Tool Chain in a Nutshell

Spring Boot API Implementation

It is recommended to explicitly specify a @ResponseStatus as this will automatically result in a cleaner OpenAPI generation later.

The API interface is implemented by a Spring @RestController. For the sake of simplicity, we implemented the storage of the user data with a non-persistent HashMap.

Finally, Maven dependencies must be added in the pom file and a @SpringBootApplication must be created and started. This is necessary to send a first request to the API via http://localhost:8080/api/users .

Up to this point, this is a simple Spring Boot infrastructure. The actual tool chain for our API roundtrip starts from here.

API Documentation Generation

SpringDoc fills this gap by automatically generating an OpenAPI specification and Swagger-UI online documentation by processing the Spring Boot infrastructure and providing additional configuration capabilities.

To be able to process SpringDoc in your own application, the following Maven-Dependency is sufficient as it indirectly refers the SpringDoc core as well:

This means that a Swagger UI can be reached immediately after a (new) start of the Spring Boot application: http://localhost:8080/swagger-ui.html

An OpenAPI specification can also be retrieved: http://localhost:8080/v3/api-docs

Both types of documentation can be extensively configured and supplemented.

SpringDoc provides various annotations, such as the @OpenAPIDefinition, for enriching the content of the API documentation as shown in the example below:

It is recommendation to add the server specification at this point. Later, during the OpenAPI file generation, the API will be started on a random free port and without explicitly specifying it here, a rather unfamiliar PORT specification will end up in the API specification.

Of course, if the final URL of the API endpoint is already known, it should be entered here.

If the JSON of the OpenAPI specification need to be formatted by a “pretty-printer” with indentations and line breaks, the following configuration should be added in the Spring Boot application.properties or yaml file:

If needed, the URLs of the Swagger UI and the OpenAPI documentation can be set under the actuator or any other context.

Finally, the OpenAPI specification must be stored as a local file to make it accessible for the client code generation later. SpringDoc comes with a Maven plugin for this step and through this, it provides more convenience compared to similar tools such as Spring Fox.

In a typical Spring Boot configuration, entire dependencies are loaded and resolved at runtime only and thus, a running application is needed by the SpringDoc Maven plugin. The plugin downloads the OpenAPI specification from the URL mentioned above.

To get this working, the SpringDoc Maven plugin is configured in the Maven “integration test” phase as shown in the example below:

In addition to the URL for downloading the OpenAPI specification, the target file can also be defined via outputFileName and outputDir parameters. We omitted these parameters in the example, so the file is written by default to target/openapi.json.

To ensure that the Spring Boot application can successfully be launched for the “integration test” phase, we first determine a free port using the codehaus build-helper-maven-plugin. The free port is then configured in the spring-boot-maven-plugin in the “pre-integration-test” phase to start the Spring Boot application (<goal>start</goal>) and stop it during the “post-integration-test” phase (<goal>stop</goal>).

The dynamic port selection ensures that the Maven tool chain works, even if an application is already running on the standard port 8080.

Now, the first step of generating an API documentation is done. Next, we will focus on generating the code for the API client and integration tests.

API Client And Integrationstest Generation

OpenAPI Generator was derived (forked) from the Swagger Code Gen project aiming at a significantly lighter and faster development. The versions released so far, and the active community of the OpenAPI Generator conform to the founder’s goal.

Meanwhile, there are over 130 different code generators, for both client and server implementations, as well as for documentation and other API and data formats such as GraphQL or protobuf.

OpenAPI comes with a Maven plugin, so the code generation can be integrated in the overall workflow straight away. A plugin for Gradle is available, too. The following example shows a concurrent Maven plugin configuration.

This example shows a plugin configuration using the Java code generator with the java8 DateLibrary option, generating date data fields as java.util.LocalDate.

In addition, the various packages for the target code are set and the generator is configured to generate only the client source code and no further documentation or Gradle and Maven artifacts.

Unfortunately, in the current version of OpenAPI Generator, the infrastructure classes to be generated still need to be specified because a feature request for a “Client Code only” setting is still open.

To combine the code generation with the previous generation of the OpenAPI specification, there are two things to consider:

  1. In the parent maven module, the api sub-module must be placed in before the client/integration test sub-modules
  2. The code generator’s path of the OpenAPI specification (<inputSpec>) must refer to the previously downloaded specification

To compile a Java client code generated with the “native” OpenAPI Generator setting, a few dependencies are required.

We provide a minimal configuration for this as a part of the example application on GitHub: https://github.com/viadee/api-roundtrip-spring-boot/blob/main/client/pom.xml

Integration test Execution

The failsafe plugin is a part of the well-established surefire plugin but its runs in the Maven integration-tests phase by default.

By default, the failsafe plugin comes with a name filter specifying the unit test classes to be executed. The following code example extends the name filter for the integration tests according to the pattern “*IntegrationTest.java”:

Additionally, the following Maven configuration ensures that the integration tests are not run by the surefire plugin during the normal testing phase and the integration test code is neither deployed nor installed in the Maven repository.

In the sample project provided on GitHub, we have encapsulated the integration test execution in a separate profile to gain even more control when we want to run it within a deployment pipeline.

Conclusion

The OpenAPI standard pushed REST API development and management to a new level and the generators and integrations based on it, promise ways out of the maintenance dilemma.

The tool chain presented in the article is entirely based on free and standard tools and takes advantage of the sophisticated Spring Boot infrastructure for REST APIs. Similar automations can also be created with frameworks such as Quarkus and Micronaut, as well as for clients in other languages such as JavaScript or Python.

For those who actively want to extend their professional expertise in API development and API management, we think it’s worth looking at OpenAPI, SpringDoc, and OpenAPI Generator.

Modern APIs are standalone products that significantly enable completely new digital business models and processes. The increasingly conscious handling of high-quality APIs helps to tap this great potential.

Similarly, automation, such as the tool chain presented in the article, helps to develop new quality standards with significantly less manual effort.

Furthermore, OpenAPI specifications provide the base for many other use cases such as public or private API directories or API quality analysis for better, more homogeneous API products.

Are your striving to professionalize your API development? I am happy to discuss your thoughts and questions with you. Just write me an email or get in touch on LinkedIn.

Dr. Benjamin Klatt, viadee

Dr. Benjamin Klatt is an Integration Architect and Agile Coach.

His focus is on the digitization of Products and Processes, Integration Architectures and Agile Methods.

Originally published at https://blog.viadee.de.

Nerd For Tech

From Confusion to Clarification

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

cloud @viadee

Written by

viadee supports you in finding and developing an individual cloud solution for your business model. We’re consultants as well as passionate hands-on-developers.

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.