prevent openapi-generator plugin from creating builder methods

129 Views Asked by At

I'm having some doubts related to the model created using openapi-generator maven plugin. The model is created based on the following yaml schema:

Context: openJDK 17.0.9 + maven 3.8.6

src/main/resources/schema.yaml:

openapi: 3.0.3
info:
  title: Test
  version: 0.0.0
paths:
  /none:
    get:
      responses:
        "200":
          description: API not generated yet
components:
  schemas:
    operation:
      type: object
      properties:
        settings:
          $ref: "./settings.yaml#/Settings"

When compiling the project, the target directory contains the following java class (target/generated-sources/openapi/src/main/java/com/test/model/)

package com.test.model;

import java.net.URI;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.openapitools.jackson.nullable.JsonNullable;
import java.time.OffsetDateTime;
import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import io.swagger.v3.oas.annotations.media.Schema;


import java.util.*;
import jakarta.annotation.Generated;

/**
 * PGP input operations file structure
 */

@Schema(name = "operation")
@JsonTypeName("operation")
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
public class OperationDTO {

  private SettingsDTO settings;

  public OperationDTO() {
    super();
  }

  /**
   * Constructor with only required parameters
   */
  public OperationDTO(SettingsDTO settings) {
    this.settings = settings;
  }

  public OperationDTO settings(SettingsDTO settings) {
    this.settings = settings;
    return this;
  }

  /**
   * Get settings
   * @return settings
  */
  @NotNull @Valid 
  @Schema(name = "settings", requiredMode = Schema.RequiredMode.REQUIRED)
  @JsonProperty("settings")
  public SettingsDTO getSettings() {
    return settings;
  }

  public void setSettings(SettingsDTO settings) {
    this.settings = settings;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    OperationDTO operation = (OperationDTO) o;
    return Objects.equals(this.settings, operation.settings);
  }

  @Override
  public int hashCode() {
    return Objects.hash(settings);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class OperationDTO {\n");
    sb.append("    settings: ").append(toIndentedString(settings)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}

I expected just constructors/getters/setters to be generated, but there is also this method in the auto-generated model class:

  public OperationDTO settings(SettingsDTO settings) {
    this.settings = settings;
    return this;
  }

I don't understand why these "builder"-alike methods are being autogenerated in the class, and I cannot find any configOption in the spring openapi-generator plugin to avoid this, nor documentation explaining why are they created

The issue is that the schema present in the swagger-ui interface is as follows:

{
  "operation":{
    "tings": "string", //<------ This attribute shouldn't be here!!!!
    "settings": {...}
  }
}

Also, when trying to validate any wrong JSON object against the schema, the exception informs about the expected parameters as follows:

Unrecognized field \"test\" (class com.test.model.OperationDTO), not marked as ignorable (2 known properties: \"settings\", \"tings\"])

It seems like the tings variable comes from Jackson detecting the settings(...) builder method as a setter, but I would like to avoid this behavior.

I understand I could avoid this by creating the model classes directly in my project, but I'd rather create them using the plugin, since the model spec can change and I find it easier to trace this way.

Can anyone please clarify why those "builder" methods are being created? Is there any way to avoid them?

Thanks a lot!

P.S: My pom.xml file looks 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.2</version>
    </parent>

    <groupId>com.test</groupId>
    <artifactId>core</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <swagger.version>2.2.20</swagger.version>
        <springdoc.version>2.3.0</springdoc.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openapitools</groupId>
            <artifactId>jackson-databind-nullable</artifactId>
            <version>0.2.6</version>
        </dependency>
        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>${springdoc.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
             <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>7.2.0</version>
                <executions>
                    <execution>
                        <id>generate-model</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.basedir}/src/main/resources/schemas/schema.yaml</inputSpec>
                            <generatorName>spring</generatorName>
                            <modelPackage>com.test.model</modelPackage>
                            <modelNameSuffix>DTO</modelNameSuffix>
                            <generateSupportingFiles>false</generateSupportingFiles>
                            <generateApis>false</generateApis>
                            <generateModelDocumentation>true</generateModelDocumentation>
                            <configOptions>
                                <useSpringBoot3>true</useSpringBoot3>
                                <openApiNullable>true</openApiNullable>
                                <useSwaggerUI>true</useSwaggerUI>
                                <hideGenerationTimestamp>true</hideGenerationTimestamp>
                                <useEnumCaseInsensitive>true</useEnumCaseInsensitive>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
0

There are 0 best solutions below