4

There is an invalid model shown on swagger UI when there is only one lowercase letter at the beginning of the field name.

My Kotlin model:

class TrendEvaluationModel(
    val xAxisValue: Int,
    val yAxisValue: Int,
    val customValue: Int?
)

What is shown on swagger UI:

{
  "customValue": 1,
  "xaxisValue": 1,
  "yaxisValue": 1
}

I've tried:

  1. @Parameter annotation with specified name attribute but it does not work.
  2. @Schema annotation with specified name attribute but it does not work.
  3. @JsonProperty("xAxisValue") and it worked but not as expected - the model on swagger showed two fields then (xaxisValue and xAxisValue) but I need only one of them (xAxisValue).

Appreciate your help.

NOTE: There is no issue if there are two or more lowercase letters at the beginning of the field name

Helen
  • 87,344
  • 17
  • 243
  • 314
VadOS
  • 41
  • 3

2 Answers2

0

Applying the @Schema annotation to the constructor fields to change the field names in Swagger UI did not have an effect. So I made those fields private and added new fields that point to the private fields. I also added @Schema and @JsonProperty annotations to the new fields to change how they show up in Swagger UI and the API request/response respectively. The final class looked like below:

import com.fasterxml.jackson.annotation.JsonProperty
import io.swagger.v3.oas.annotations.media.Schema

class TrendEvaluationModel(
    @Schema(hidden = true)
    private val xAxisVal: Int,
    @Schema(hidden = true)
    private val yAxisVal: Int,
    val customValue: Int?
) {
    val xAxisValue: Int
        @Schema(name = "xAxisValue")
        @JsonProperty("xAxisValue")
        get() = xAxisVal

    val yAxisValue: Int
        @Schema(name = "yAxisValue")
        @JsonProperty("yAxisValue")
        get() = yAxisVal
}

This class shows up like below, with the correct field names, in Swagger UI:

{
  "customValue": 0,
  "xAxisValue": 0,
  "yAxisValue": 0
}

You can find a working sample app that uses this class on github

devatherock
  • 2,423
  • 1
  • 8
  • 23
-1

The cause of this problem seems to Kotlin Decompiler. It seems that this is because the character after get is changed to capital letters, and then changed again by Jackson's PropertyNamingStrategy.

I haven't found a solution yet either....

BEFORE:

data class TestVo(
        val vCPU: Int,
        val vvCPU: Int
    )

AFTER:

public static final class TestVo {
      private final int vCPU;
      private final int vvCPU;

      public final int getVCPU() {
         return this.vCPU;
      }

      public final int getVvCPU() {
         return this.vvCPU;
      }

      public TestVo(int vCPU, int vvCPU) {
         this.vCPU = vCPU;
         this.vvCPU = vvCPU;
      }

      public final int component1() {
         return this.vCPU;
      }

      public final int component2() {
         return this.vvCPU;
      }

      @NotNull
      public final TestVo copy(int vCPU, int vvCPU) {
         return new TestVo(vCPU, vvCPU);
      }

      // $FF: synthetic method
      public static TestVo copy$default(TestVo var0, int var1, int var2, int var3, Object var4) {
         if ((var3 & 1) != 0) {
            var1 = var0.vCPU;
         }

         if ((var3 & 2) != 0) {
            var2 = var0.vvCPU;
         }

         return var0.copy(var1, var2);
      }

      @NotNull
      public String toString() {
         return "TestVo(vCPU=" + this.vCPU + ", vvCPU=" + this.vvCPU + ")";
      }

      public int hashCode() {
         return Integer.hashCode(this.vCPU) * 31 + Integer.hashCode(this.vvCPU);
      }

      public boolean equals(@Nullable Object var1) {
         if (this != var1) {
            if (var1 instanceof TestVo) {
               TestVo var2 = (TestVo)var1;
               if (this.vCPU == var2.vCPU && this.vvCPU == var2.vvCPU) {
                  return true;
               }
            }

            return false;
         } else {
            return true;
         }
      }
   }
1mm.p
  • 37
  • 5