icon / menu / white V2Created with Sketch.
Switch LanguageSwitch Language
Spring Boot: Client - and server code generation using OpenAPI 3 Specs

Spring Boot: Client - and server code generation using OpenAPI 3 Specs

REST APIs are ubiquitous in today's world, ranging from payments, to communication, to banking. Developers can plug-in virtually any specialist service they require for their applications.

So, it comes as no surprise that we at PALO IT are frequently developing APIs for our customers and integrating external APIs with our backend applications. Both our own APIs and external ones can become rather large and extensive, making it time consuming to write them all by hand. Luckily, there are some nifty techniques to make our lives as developers easier and avoid writing repetitive code.

Enter OpenApi 3 specs and code generation!

Imagine someone needs to access our freshly developed API. In the past, we would share our endpoint definitions using a non-standardised way, such as Excel sheets. The consumers of our API would have to implement a client within their application. With large APIs, this can take quite a while. To avoid re-inventing the wheel, the open API spec was created. It enables us to define our REST API contract in a standardised format and easily share it with others.

Thus, an ecosystem of editors and code generation tools were created around the open API specification (of which the latest version is 3.1 at the time of writing). These tools allow us to create API documentation and generate both clients and servers for a vast multitude of programming languages and frameworks. This article will focus on utilising code generation with the popular Java Spring Boot framework which is used in more than a few of our projects.

Definitions

Before we jump into the code, we need to establish some definitions...

Open API specification

The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.

Client code

Client code is any client SDK that enables us to call a remote REST API. In the context of Spring Boot, client code is usually written using HTTP clients such as the Rest Template or the more recently introduced Webclient.

Server code

Server code refers to any code necessary to create a REST API server. Using Spring Boot, this is usually accomplished with the servlet-api based Spring Web or the newer, non-blocking Spring Webflux.

Code generation

The code generation we will learn about in this tutorial will be done using the OpenAPI Generator. It is a community project widely used by many well-known companies and can generate client code or server stubs from an open API spec in a multitude of programming languages and frameworks. There are many ways to use the generator. It comes as a maven plugin, npm module and standalone JAR. In the following sections we will utilise the maven plugin for convenience, since the Spring Boot project uses it as the build management tool.

On a side note, the OpenAPI Generator was forked from the Swagger Codegen to simplify the original and enable stronger community ownership.


Tutorial Scope

With this tutorial, we will demonstrate how to generate both server-side and client-side code from an Openapi 3 specification. The v3 specification is the latest Openapi iteration and extends the older v2 version with numerous new functionalities and improvements.

For simplicity's sake, the Swagger Petstore will be used for the generation. It is a simple example REST API demonstrating the capabilities of the Open API specification including authorisation, HTTP schemes and API descriptions.

Server

For the server-side, the generator will output traditional Spring Web based code.

Client

To illustrate the client code generation, the reactive WebClient will be used. For our projects, we at PALO IT prefer to use the Webclient because it simplifies performing concurrent calls compared to the Rest Template. Also, the RestTemplate is no longer in active development and remains in maintenance mode. Thus, the WebClient should be preferred for new projects.


Prerequisites

Before getting started, we need to ensure all necessary tools to run the application are available. The tools and installation instruction are below.


Project structure

To become familiar with the components and structure of the project, the main areas of interest are depicted below.

The Petstore Openapi specification in YAML format is kept in the src/main/resources/openapi folder. Both server and client contain the same spec but have been kept in separate folders for simplicity.

  1. The generated WebClient code
  2. Common configuration for the WebClient, SpringDoc API documentation and Jackson parser
  3. The generated Spring Web server stubs
  4. Adjustment for the generation templates. Sometimes custom adjustments are needed for the generation process if the default templates are not sufficient. More about this in custom generator templates
  5. Tests for both generated server and client

The configuration for the OpenAPI Generator can be found in the pom file. To separate configuration for the client- and server generator, maven profiles have been used as seen below.

Spring Web server generator configuration

WebClient generator configuration

Getting Started

Clone the Git repository.

Import the maven project inside the  spring-boot-openapi-codegen using your favorite IDE.

Generate client

Navigate to the project using a terminal and execute the following command to generate the client code.

The generated code can be found in the target directory.

 
  1. Contains the generated APIs
  2. Shared classes related to authorization
  3. Generated models
  4. Re-usable shared support classes

After the generation is complete, the API and model packages (1. and 3.) are copied to com.paloit.clientpetstore.webclientThe support and authorisation classes are copied as well and contained in the apiclient and auth packages.

Client initialization & usage

The client has to be defined as a spring bean. This is done within the com.paloit.config.ApiClientConfig class. A simple example is depicted below and should be self-explanatory.

After defining the PetApi as a Spring Bean, it can be auto-wired and used to call the external API as illustrated below.

Custom generator templates

The OpenAPI Generator uses mustache templates to generate client implementations or server stubs. For the majority of cases, these are sufficient to be used out of the box. For custom use cases, they can be adjusted to generate the desired code.

The templates for all programming languages supported by the generator can be found in their git repository.

The templates can be overridden with the OpenAPI Generator maven configuration using the templateDirectory tag. If a template with the same file name as the original is found in the specified directory, it will override the default template.

 

The overridden templates for the WebClient were copied to the local /src/main/resources/generator-template-overrides/webclient directory from the openapi-generator/src/main/resources/Java/libraries/webclient folder in the OpenAPI Generator Git repository.

In this example, the generator templates are used to change a modifier with the generated client to access the ResponseSpec and enable us to have fine-grained handling of HTTP errors. By default, the PetApi client method addPet only returns a Mono as seen below and the addPetRequestCreation method is private.

The api.mustache template is changed at line 72 so the addPetRequestCreation method becomes public and accessible. The relevant change is depicted below in bold.

Generate server

The server is generated in a similar fashion and illustrates the API first development approach. The open API spec is created first and a server stub is generated from it. The development team then adds implementations for the API.

In order to be able to re-generate the server at any time without affecting the implementations, the delegate pattern is utilized and will be further explained below.

Navigate to the project root using a terminal and execute the following command to generate the server code.

The generated code can again be found under the target folder.

After completing the generation, the API and model packages are copied to the  server.petstore package. The implementations will be kept in the  controller  package and have to implement the delegate interfaces. The delegate interfaces define default implementations for all APIs and return a HTTP 501 (Not Implemented) if not overridden.

The PetApiController uses either the default PetApiDelegate if we do not define our own. However, if we define our own with custom implementations as depicted below, it will be automatically used.

Note that our delegate implementation has to be a spring bean and the @Component annotation is added on top of the class.

The delegate pattern effectively separates the definition of the API from its implementation and both can be modified independently. The default delegate, API and models can be re-generated without affecting the implementation and vice-versa.

Run application

Use below command to start the application. A swagger UI web interface can be accessed under http://localhost:8090/openapi to inspect and interact with the REST API.

Run tests

Conclusion

In this article, we've demonstrated how to speed up development with Spring Boot using client- and server code generation. Using these techniques has helped our team of experts at PALO IT to rapidly develop our own REST APIs and integrate external ones with our applications. By openly sharing our approach to development, we hope that it will benefit you, our dear readers, and spark some interest in our other practices. Open source ftw!


Get in touch

PALO IT is always looking for passionate developers to join our team. Are you interested in learning, coding, and applying cutting edges technologies to empower our customers and make the world a better place? Don't think twice and apply here!

Interested in developing your own REST APIs? Tap into our team of experts, and let's build something awesome, together.

CONTACT US

Related articles

The Rise of Hybrid Cloud: Balancing Security, Flexibility and Cost Optimization
4 mins
Tech trends
The Rise of Hybrid Cloud: Balancing Security, Flexibility and Cost Optimization
AI Use Case: Intelligent Document Processing and Summarization
1 mins
Tech trends
AI Use Case: Intelligent Document Processing and Summarization
AI Use Case: Automating Insurance Claim Processing from End to End
2 mins
Tech trends
AI Use Case: Automating Insurance Claim Processing from End to End

Button / CloseCreated with Sketch.