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

In the API community, much like any traditional type of interface, it is often discussed whether to start with an interface specification and implement the rendering API afterwards (API-Design-First) or to generate the specification from the implementation (Code-First). Both approaches are justifiable. In this article, we will focus on the use cases with a code-first approach, as is often done with Spring Boot.

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

As an case for this article, we provide a User API example project. This services as a reference for the presented tool chain and will likely support you in setting up the tool chain for your own context.

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

In this article, we refer to an API roundtrip as the development of a complete API package including the following artifacts:

  • 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

It is fairly established for other interface types such as SOAP or CORBA to provide documentation (WSDL) and pre-built clients. However, such artifacts are far from being common for REST APIs. A significant reason for this is the lack of established automation - or at least the established automation not being commonly known.

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

For an effective REST API development improving the status quo, an automated tool chain providing capabilities, at least known from using SOAP and CORBA, is desirable. On one hand, this automates repetitive manual tasks, on the other hand, this resolves the media break in the integration test development.

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

The User API is defined by an interface with corresponding spring annotations. The method names should be chosen with care. By default, they will be used as operationID in the OpenAPI Spec and through this, define the method names of the generated API clients.

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

With SOAP Web Services, it is quite common to provide a WSDL and get it automatically generated by the web service infrastructure. However, this is not yet available out-of-the-box for REST APIs.

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 specifications provide a detailed interface description which is sufficient to implement valid requests to the API endpoints. OpenAPI Generator is an quite active and mature open-source tool for generating code and other artifacts based on these specifications. We use it in the roundtrip tool chain for generating code that encapsulates the REST API calls as easy-to-use Java interfaces.

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

If the integration tests are generated in addition to the pure client code, one valid strategy is to implement them as unit tests, but running them separately with the Maven failsafe and not with the classic surefire plugin. The whole setup becomes even more practical if the integration tests are in a separate maven module, which specifies extra rules such as not bundling integration tests with the overall application.

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

REST APIs have been adopted widely because of their simplicity. However, this simplicity also comes with many challenges, especially for maintenance and sustainability.

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/. Don’t forget to check out Ask-NFT, a mentorship ecosystem we’ve started

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/. Don’t forget to check out Ask-NFT, a mentorship ecosystem we’ve started

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store