Generate Spring MVC controller from Swagger/OpenAPI - java

Is there a way how to generate controller Spring MVC code from Swagger/OpenAPI specification?
I know Swagger can be generated from existing Spring code but is this possible the other way round ?

You are basically looking for generation of swagger server-side code. If you would like to generate it while you are building your application and if you are using maven you can use the following plugin:
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>${swagger.codegen.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${swagger.yaml.file}</inputSpec>
<language>spring</language>
<configOptions>
<sourceFolder>${swagger.generated.sourcepath}</sourceFolder>
<!-- <interfaceOnly>true</interfaceOnly> -->
<dateLibrary>java8</dateLibrary>
</configOptions>
<typeMappings>
<typeMapping>OffsetDateTime=Instant</typeMapping>
</typeMappings>
<importMappings>
<importMapping>java.time.OffsetDateTime=java.time.Instant</importMapping>
</importMappings>
<modelPackage>${project.groupId}.${project.artifactId}.swagger.model</modelPackage>
<apiPackage>${project.groupId}.${project.artifactId}.swagger.api</apiPackage>
<invokerPackage>${project.groupId}.${project.artifactId}.swagger.invoker</invokerPackage>
</configuration>
</execution>
</executions>
</plugin>
Please note the commented part interfaceOnly if set to true, it will only create the APIs class with default as NOT_IMPLEMENTED and you would have to write the implementation.
Add following dependency:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.annotations.version}</version>
<scope>compile</scope>
</dependency>
I used the following properties:
<properties>
<swagger.codegen.version>2.4.1</swagger.codegen.version>
<swagger.yaml.file>${project.basedir}/swagger.yaml</swagger.yaml.file>
<swagger.annotations.version>1.5.21</swagger.annotations.version>
<swagger.generated.sourcepath>src/main/java</swagger.generated.sourcepath>
</properties>
The other static approach that would require the generation of controller manually when there is a change in the swagger file would be to use swagger editor.

Yes it is possible using swagger codegen from the command line or using swagger editor.

Related

Mustache + Spring boot + REST API

I decided to make a project using Mustache + Spring Boot + REST API. Earlier, I used to write projects with the front-end used Java EE + Servlets + JSP. Now I decided to try to switch to Spring and write an application with a front-end. And I found a way to create a page on the front-end using Mustache, but if you use Mustache, then everything needs to be saved to the model, and I want to use REST API. I mean if it is possible? If it's possible I'll be happy if you show a piece of code your RestController and Mustache.
The question is 'if possible call endpoint from mustache?'.
Yes, You can create REST API using OpenAPI(https://support.smartbear.com/swaggerhub/docs/tutorials/openapi-3-tutorial.html) which uses the mustache file to create your code.
You need to add following dependencies,
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.2</version>
</dependency>
add the following plugin in the pom.xml for configuration(https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator-maven-plugin/README.md),
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.0.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<templateDirectory>${project.basedir}/templates
</templateDirectory>
<configOptions>
//add the configuration options here
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
By default it uses the mustache files internally to generate codes, you can change the mustache files from the git location(https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/JavaSpring/)/create your own with the name mentioned in git and place it in the location ${project.basedir}/templates it will generate your codes during the compile time and you can use them in your project.
Place the OpenAPI document in the resource folder where application.properties is placed

Maven plugin jsonschema2pojo returns ClassNotFoundException

I need to generate java pojos from JSON schema. I'm trying to use jsonschema2pojo maven plugin for this purpose. I wrote custom rule factory and I want to use it for pojos generation.
Here is my jsonschema2pojo plugin configuration:
<plugin>
<dependencies>
<dependency>
<groupId>my.group.id</groupId>
<artifactId>my-artifact-id</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<id>generateClassesFromSchema</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>${basedir}/src/main/resources/schemas</sourceDirectory>
<targetPackage>my.target.package</targetPackage>
<includeHashcodeAndEquals>false</includeHashcodeAndEquals>
<customRuleFactory>path.to.rule.factory.MyCustomRuleFactory</customRuleFactory>
</configuration>
</plugin>
MyCustomRuleFactory.java is the part of my project, dependency for which is inside plugin element. But when a do mvn clean install I get thi following:
Failed to execute goal org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.1.1:generate (generateClassesFromSchema) on project my-artifact-id: Execution generateClassesFromSchema of goal org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.1.1:generate failed: java.lang.ClassNotFoundException: path.to.rule.factory.MyCustomRuleFactory
What am I doing wrong?
Thanks for any suggestion!
As I understand in the tag "customRuleFactory" must be full class name. Are you sure you didn't add path?
path.to.rule.factory.MyCustomRuleFactory
May be correct rule.factory.MyCustomRuleFactory

java liquibase maven plugin safe store password

Im using liquibase in a standard java project (non spring) and using maven to manage my migrations and rollbacks
to the plugin configuration in maven im passing a liquibase.properties file that currently has a plain password in it
here is the relevant code
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>4.3.3</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
<executions>
<execution>
<phase>process-resources</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.liquibase.ext</groupId>
<artifactId>liquibase-postgresql</artifactId>
<version>4.3.3</version>
</dependency>
</dependencies>
</plugin>
and the properties file
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost:5432/testdb
username=test
password=test
changeLogFile=src/main/resources/db/changelog-master.xml
how can i avoid this
You may use your own property provider class to handle encryption. I don't see any docs for this but you can browse the commits on this link, it might help.
Also the answer on this post will help you with using propertyProviderClass in liquibase.
Other than this, you can go through this article to have an idea.

Generating Java classes for Request and Response objects from Yaml file

We have created a Yaml file using Swagger editor for our APIs specification which includes Base URL, endpoint, Request, Response and Header information etc.. Now I want to implement RESTful web service for these APIs. For that I am thinking of generating my Request and Response Java classes from this Yaml file and was looking for some kind of code generator, preferably a maven plugin/dependency which I could use in my Maven project. I came across this rest client with swagger which talks about using the swagger-codegen Maven plugin, but this is to generate the client which I believe is about generating the client code to consume these RESTful APIs, however my need is to generate classes to be used for service implementation. I will be using Java and Spring framework.
My question is what are the best practices for implementing the RESTful web services in Java when we have Yaml file (API spec created using Swagger editor) and which code generation tools/plugins are available to be used.
EDIT: Just came across this Server stub generator HOWTO, looking further into it.
Swagger-codegen maven plugin is a good option but I suggest you to use jhipster to generate your java project. It generates projects with latest tech stack including spring framework. You can select API-First development in your case. I used it and it was very efficient. You already have Yaml file. Put it in src/main/resources/swagger/api.yml and run
./mvnw generate-sources
All java codes will be generated.
Using swagger-codegen-maven plugin like the following
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.4.29</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${basedir}/src/main/resources/swagger/project.yaml</inputSpec>
<language>java</language>
<configOptions>
<sourceFolder>src/gen/java/main</sourceFolder>
<library>resteasy</library>
</configOptions>
</configuration>
</execution>
</executions>
or using openapi-generator-maven-plugin
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.3.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>
${project.basedir}/src/main/resources/swagger/project.yaml
</inputSpec>
<generatorName>spring</generatorName>
<apiPackage>where api package is to be rendered</apiPackage>
<modelPackage> model package </modelPackage>
<supportingFilesToGenerate>
Any supporting files needed </supportingFilesToGenerate>
<configOptions>
<delegatePattern>true</delegatePattern>
</configOptions>
</configuration>
</execution>
</executions>

How to use a custom strategy with the jOOQ code-generator and Maven?

With jOOQ, I may want to combine using the jOOQ code generator with Maven and a custom generator strategy. It looks as though this can be done as such (leaving out irrelevant parts):
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>2.2.2</version>
<!-- The plugin should hook into the generate goal -->
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generator>
<name>org.jooq.util.DefaultGenerator</name>
<!-- But the custom strategy is not yet compiled -->
<strategy>
<name>com.example.MyStrategy</name>
</strategy>
</generator>
</configuration>
</plugin>
The above configuration depicts the problem. jOOQ's code generator hooks into the generate goal of the Maven lifecycle, which takes place before the compile goal of the lifecycle. For code generation, however, it needs a pre-compiled custom strategy class, or I will get a ClassNotFoundException. How can this be resolved with Maven? Can I compile a single class before executing the generate goal?
A much better solution is to split the project into two modules. One contains the strategy and the other the rest.
Using modules, you can compile the strategy in an independent step and then use that module in the plugin:
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>2.2.2</version>
...your config goes here...
<dependencies>
list your strategy module here
</dependencies>
</plugin>

Categories

Resources