Contribute to help us improve!
Are there edge cases or problems that we didn't consider? Is there a technical pitfall that we should add? Did we miss a comma in a sentence?
If you have any input for us, we would love to hear from you and appreciate every contribution. Our goal is to learn from projects for projects such that nobody has to reinvent the wheel.
Let's collect our experiences together to make room to explore the novel!
To contribute click on Contribute to this page on the toolbar.
Open Api Generator
OpenApi is a specification to describe restful service endpoints in a human and computer readable format.
With the help of a generator, server and client code can be created from the Api definition. This will help to build projects more Api driven, faster, consistent and in a design first approach.
-
For the client-side, it’s easier to send requests to the Api by using a generated Api client
-
For the server-side, stubs are generated as interfaces to implement
Generator to use
There are different types of generators, it is suggested to use the OpenApi Generator.
It’s sugessted to use the maven/gradle plugin version for the client and server.
For the client, there is also a cli tool. The advantage of this tool is the creation of the client as a library in a local or remote maven repository. This will improve build times because the client only has to be generated once. After running the generator, view the created README for more details about installation and usage.
Setup
Create an openapi.yaml file from the Api and move it into the main/resources
folder.
Configure the openapi generator maven plugin inside the pom.xml
.
Use generated as package name
-
The code generated for the
server
should be located under <root-package>.generated.api -
The code generated for the
client
should be located under <root-package>.generated.client
Before generating, choose the underlying httpClient library
When generating a client, the client encapsulates the HttpClient library, making it easy to exchange. The library can be set by changing the library
option inside the plugin configuration.
Some minor changes need to be done when changing the library.
For native Java library, the method for changing the server path is updateBaseUri
.
For other libraries, it is setBasePath
. When switching, this needs to be changed. See the example for the details.
Dependent on the library, error handling can be different.
For client-side
A detailed guide on how to use the generated client code can be found here
Configure The APIClient and Specific clients in a Configuration Bean
The ApiClient should be configured in a Configuration Bean named {[ApiName]}Config
It is possible that the server url is already set inside the openapi.yaml file. You can set/overwrite the server path of the Api inside the application.properties using the configuration bean.
For different http libraries, the configuration bean has to be changed.
Code Snippets to integrate the generation in the build tools
plugins { ... id "org.openapi.generator" version "6.2.0" ... } sourceSets.main.java.srcDirs += 'build/generated-sources/server/src/main/java' (1) dependencies { (2) ... implementation 'io.swagger.parser.v3:swagger-parser:2.1.7' implementation 'org.openapitools:jackson-databind-nullable:0.2.4' ... } openApiGenerate { artifactId = "MyThaiApi-java-client" groupId = "com.devonfw.generated.client" apiPackage = "com.devonfw.generated.client.service" modelPackage = "com.devonfw.generated.client.model" invokerPackage = "com.devonfw.generated.client.handler" inputSpec = "${rootDir}/src/main/resources/MyThaiApi.yml" (3) output = "${buildDir}/generated-sources/client" generatorName = "java" (4) library = "native" (5) generateApiTests = "false" generateModelTests = "false" modelNameSuffix = "To" } tasks.compileJava.dependsOn(tasks.openApiGenerate) (5)
1 | Add the generated sources to the sourceSets, otherwise the IDE will not know the generated files and mark them. Also autocompletion would not work. |
2 | Add the dependencies that are necessary for the generated sources |
3 | Path to the openapi spec |
4 | The generator java is a client generator. See https://openapi-generator.tech/docs/generators#config-generators. |
5 | The library defines with which http library the calls should be generated |
<!--Generation dependencies--> <dependencies> ... <dependency> <groupId>io.swagger.parser.v3</groupId> <artifactId>swagger-parser</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.openapitools</groupId> <artifactId>jackson-databind-nullable</artifactId> <version>0.2.3</version> </dependency> ... </dependencies> <build> <plugins> ... <plugin> <groupId>org.openapitools</groupId> <artifactId>openapi-generator-maven-plugin</artifactId> <version>6.1.0</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <artifactId>MyThaiApi-java-client</artifactId> <groupId>com.devonfw.generated.client</groupId> <apiPackage>com.devonfw.generated.client.service</apiPackage> <modelPackage>com.devonfw.generated.client.model</modelPackage> <invokerPackage>com.devonfw.generated.client.handler</invokerPackage> <inputSpec>${project.basedir}/src/main/resources/MyThaiApi.yml</inputSpec> <output>${project.build.directory}/auto-generated</output> <generatorName>java</generatorName> <library>native</library> <generateApiTests>false</generateApiTests> <generateModelTests>false</generateModelTests> <modelNameSuffix>TO</modelNameSuffix> </configuration> </execution> </executions> </plugin> </plugins>
For server-side
A detailed guide on how to use the generated server code can be found here
The content type for the response is defined inside the openapi file. If there are multiple response types and xml should be used as default, add the following in the plugin configuration.
<singleContentTypes>false</singleContentTypes>
<withXml>true</withXml>
Code Snippets to integrate the generation in the build tools
plugins { ... id "org.openapi.generator" version "6.2.0" ... } sourceSets.main.java.srcDirs += 'build/generated-sources/server/src/main/java' (1) dependencies { (2) ... implementation 'io.swagger.parser.v3:swagger-parser:2.1.7' implementation 'org.openapitools:jackson-databind-nullable:0.2.4' ... } openApiGenerate { // other settings omitted inputSpec = "${rootDir}/src/main/openapi/BookingOpenApi.yaml" (3) outputDir = "${buildDir}/generated-sources/server" generatorName = "spring" library = "spring-boot" (4) modelNameSuffix = "To" apiPackage = "com.devonfw.generated.api.service" modelPackage = "com.devonfw.generated.api.model" invokerPackage = "com.devonfw.generated.api.handler" configOptions = [ sourceFolder : "src/main/java", interfaceOnly : "true", serializableModel : "true", singleContentTypes: "true", ] } tasks.compileJava.dependsOn(tasks.openApiGenerate) (5)
1 | Add the generated sources to the sourceSets, otherwise the IDE will not know the generated files and mark them. Also autocompletion would not work. |
2 | Add the dependencies that are necessary for the generated sources |
3 | Path to the openapi spec |
4 | Depending on the library the annotations are different. Here we define spring-boot. |
5 | Add a dependeny from compile to openApiGenerate so that the sources are generated before the compile task. |
<!--Generation dependencies--> <dependencies> ... <dependency> <groupId>io.swagger.parser.v3</groupId> <artifactId>swagger-parser</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.openapitools</groupId> <artifactId>jackson-databind-nullable</artifactId> <version>0.2.3</version> </dependency> ... </dependencies> <build> <plugins> ... <plugin> <groupId>org.openapitools</groupId> <artifactId>openapi-generator-maven-plugin</artifactId> <version>6.1.0</version> <executions> <execution> <id>server-generator</id> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/MyThaiApi.yml</inputSpec> <output>${project.build.directory}/generated-sources/server</output> <generatorName>spring</generatorName> <library>spring-boot</library> <modelNameSuffix>To</modelNameSuffix> <apiPackage>com.devonfw.generated.api.service</apiPackage> <modelPackage>com.devonfw.generated.api.model</modelPackage> <invokerPackage>com.devonfw.generated.api.handler</invokerPackage> <configOptions> <sourceFolder>src/java/main</sourceFolder> <interfaceOnly>true</interfaceOnly> <serializableModel>true</serializableModel> <singleContentTypes>true</singleContentTypes> </configOptions> </configuration> </execution> </executions> </plugin> </plugins>