theINtoy
theINtoy

Reputation: 3708

OpenApi 3.0 SpringBoot Controller use

Using the openapi maven plugin:

<dependency>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>4.2.2</version>
</dependency>

and generating spring boot controllers using a pom config like:

     <plugin>
        <groupId>org.openapitools</groupId>
        <artifactId>openapi-generator-maven-plugin</artifactId>
        <version>4.2.2</version>
        <executions>
          <execution>
            <id>spring-server</id>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <!-- specify the swagger yaml -->
              <inputSpec>${project.resources[0].directory}/pet-store.yaml</inputSpec>
              <!-- target to generate java client code -->
              <generatorName>spring</generatorName>
              <!-- pass any necessary config options -->
              <configOptions>
                <serializableModel>true</serializableModel>
                <snapshotVersion>true</snapshotVersion>
              </configOptions>

            </configuration>
          </execution>

        </executions>
      </plugin>

will generate a controller like this:

@Controller
@RequestMapping("${openapi.openAPIPetstore.base-path:/v2}")
public class StoreApiController implements StoreApi {

    private final NativeWebRequest request;

    @org.springframework.beans.factory.annotation.Autowired
    public StoreApiController(NativeWebRequest request) {
        this.request = request;
    }

    @Override
    public Optional<NativeWebRequest> getRequest() {
        return Optional.ofNullable(request);
    }

}

This is great, but how do I bind in to this to add the business logic without changing the actual generated code? If I extend the controller to add the business logic I get all kinds of issues.

How are you supposed to use this generated code, to extend it to add the correct business logic without changing the generated code which would be bad.?

Upvotes: 4

Views: 6226

Answers (1)

tim82
tim82

Reputation: 102

I came across your question as I was trying to cope with OAS 3.0 and therefore using the mentioned openapi-generator-maven-plugin. Meanwhile I got it to generate exactly what you are describing.

I would suggest dealing with this by

  1. generating your model and API classes to a separate package from your code and
  2. configuring Spring's @ComponentScan annotation to not include the generated classes (either with the basePackages property alone or combining it with the explicit excludeFilters property).

And yes, modifying generated classes is bad. I'd just use them as a starting point for creating your actual controllers.

Amendment: After configuring the code generation in various ways I found the best solution to have only the API (interfaces) being created. This way I can implement my controller without having another implementation interfering with it.

To achieve this my plugin config now looks like this (using the configOptions/interfaceOnly option):

            <plugin>
                <!-- generate REST API from spec -->
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>4.2.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
                            <generatorName>spring</generatorName>
                            <generateModels>true</generateModels>
                            <generateApis>true</generateApis>
                            <generateApiDocumentation>true</generateApiDocumentation>
                            <generateSupportingFiles>true</generateSupportingFiles>
                            <modelPackage>example.openapi.model</modelPackage>
                            <apiPackage>example.openapi.api</apiPackage>
                            <package>example.openapi</package>
                            <output>${generated.sources.restapi.dir}</output>
                            <configOptions>
                                <interfaceOnly>true</interfaceOnly>
                                <dateLibrary>java8-localdatetime</dateLibrary>
                                <java8>true</java8>
                                <useBeanValidation>true</useBeanValidation>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Upvotes: 5

Related Questions