Generate Java module for OpenAPI from Swagger YAML in maven

Let's say the analytics department prepared Swagger YAML for us with a description of the API access to some service: xyz-swagger-v1.0.0.yaml.
How to automate the generation of a library to access the API using this description if you have maven? For some reason, there is no full manual anywhere, so I collected all the information about the implementation and possible problems in one place.

For generation we will need the following maven plugins:

  • maven-clean-plugin — deletes files. It is needed to clear the directory with the project sources from the previous generated version. Settings that you should pay attention to:

    • configuration.filesets.fileset.directory: ${project.basedir}/src/main/java – we will clean the directory of the application itself

    • configuration.filesets.fileset.includes.include: ** — not only clean the directory /src/main/javabut also to delete it itself.

  • openapi-generator-maven-plugin — generates Java classes for Swagger via OpenAPI YAML. Settings to pay attention to:

    • apiPackage — namespaces for API service classes

    • modelPackage — namespaces for model classes

    • output: ${project.basedir} — if you set it up like this, the generated files would not fall into the target, but directly into the folder with the code

The generated files use annotations and methods from external libraries. Therefore, in dependencies you will need to add:

  • spring-boot-starter-web versions 2.4.4

  • spring-data-jpa versions versions 2.4.6

  • jackson-databind-nullable versions 0.2.6

  • springdoc-openapi-ui versions 1.8.0

If any of these versions are not in the repositories available to your project, use those that are. But increase the version carefully and double-check after each change: at least spring-boot-starter-web and spring-data-jpa are not completely backward compatible and may stop recognizing dependencies in generated files when increasing their version.

Create an empty Maven enabled project and delete all code from the java folder.

Place a file with a YAML description of OpenAPI for Swagger in the /src/main/resources/ folder. In my example, it is xyz-swagger-v1.0.0.yaml

As a result pom.xml will look something like this:

<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.mycompany</groupId>
    <artifactId>xyz-api-service</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
	    <maven.compiler.source>17</maven.compiler.source>
	    <maven.compiler.target>17</maven.compiler.target>
	    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	    <spring-boot-starter-web.version>2.4.4</spring-boot-starter-web.version>
	    <spring-data-jpa.version>2.4.6</spring-data-jpa.version>
	    <jackson-databind-nullable.version>0.2.6</jackson-databind-nullable.version>
        <springdoc-openapi-ui.version>1.8.0</springdoc-openapi-ui.version>
	    <openapi-generator-maven-plugin.version>7.1.0</openapi-generator-maven-plugin.version>
	    <maven-clean-plugin.version>2.4.1</maven-clean-plugin.version>
	    <swagger-yaml>xyz-swagger-v${swagger-yaml.version}.yaml</swagger-yaml>
	    <swagger-yaml.version>1.0.0</swagger-yaml.version>
    </properties>
    <dependencies>
		<dependency>
			    <groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-starter-web</artifactId>
				<version>${spring-boot-starter-web.version}</version>
			</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data-jpa.version}</version>
        </dependency>
	    <dependency>
		    <groupId>org.openapitools</groupId>
		    <artifactId>jackson-databind-nullable</artifactId>
		    <version>${jackson-databind-nullable.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-ui</artifactId>
			<version>${springdoc-openapi-ui.version}</version>
		</dependency>
	</dependencies>
    <build>
	    <plugins>
		    <plugin>
			    <artifactId>maven-clean-plugin</artifactId>
			    <version>${maven-clean-plugin.version}</version>
			    <configuration>
				    <filesets>
					    <fileset>
						    <directory>${project.basedir}/src/main/java</directory>
							<includes>
								<include>**</include>
							</includes>
							<followSymlinks>false</followSymlinks>
						</fileset>
					</filesets>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.openapitools</groupId>
				<artifactId>openapi-generator-maven-plugin</artifactId>
				<version>${openapi-generator-maven-plugin.version}</version>
				<executions>
					<execution>
						<goals>
							<goal>generate</goal>
						</goals>
					<configuration>
						<inputSpec>${project.basedir}/src/main/resources/${swagger-yaml}</inputSpec>
						<generatorName>spring</generatorName>
						<apiPackage>org.mycompany.xyz.api</apiPackage>
						<modelPackage>org.mycompany.xyz.model</modelPackage>
						<supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate
						<configOptions>
							<delegatePattern>true</delegatePattern>
						</configOptions>
						<output>${project.basedir}</output>
					</configuration>
				</execution>
			</executions>
			</plugin>
	    </plugins>
    </build>
</project>

When updating the file version, it will be enough to replace the swagger-yaml.version property. And the file name format is specified in the swagger-yaml property.

To generate the files, simply run two Maven lifecycle commands from the console or your IDE interface: clean and compile.

And the generated files will appear directly in the working directory. When a new generation occurs, old files will be deleted automatically

Important: Do not try to run the plugins listed directly. They simply will not work directly.

A small touch – to avoid littering the repository, you need to add to .gitignore (for Git, in Mercurial this file is called .hgignore) a note that you should ignore the temporary files that the plugin creates:

.openapi-generator

Similar Posts

Leave a Reply

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