OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
20.62k stars 6.29k forks source link

[BUG][Go] Query parameter with oneOf enum doesn't work with defaultValue #16574

Open AlanCitrix opened 10 months ago

AlanCitrix commented 10 months ago

Bug Report Checklist

Description

When using an enum schema with oneOf and default, the new default value handling from #15126 causes the generated code to not build.

openapi-generator version

master @ 8b15d482

OpenAPI declaration file content or url
openapi: 3.1.0
info:
  description: 'Minimium viable reproduction for issue 16574'
  version: 1.0.0
  title: OpenAPI Petstore
paths:
  /pet/findByStatus:
    get:
      tags:
        - pet
      summary: Finds Pets by status
      description: Find pets by a single status
      operationId: findPetsByStatus
      parameters:
        - name: status
          in: query
          description: Status value that needs to be considered for filter
          schema:
            default: "available"
            oneOf:
              - $ref: '#/components/schemas/StatusType'
      responses:
        '200':
          description: successful operation
          content:
            application/xml:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
        '400':
          description: Invalid status value
components:
  schemas:
    StatusType:
      type: string
      enum:
        - available
        - pending
        - sold
    Pet:
      title: a Pet
      description: A pet for sale in the pet store
      type: object
      required:
        - name
        - photoUrls
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
          example: doggie
        status:
          $ref: '#/components/schemas/StatusType'
      xml:
        name: Pet
Generation Details
> java -jar .\openapi-generator-cli.jar generate -g go -o petstore -i petstore.yaml  --package-name petstore -t C:\repos\openapi-generator\modules\openapi-generator\src\main\resources\go

Generates the following invalid go:

    if r.status != nil {
        parameterAddToHeaderOrQuery(localVarQueryParams, "status", r.status, "")
    } else {
        var defaultValue interface{} = available
        r.status = &defaultValue
    }
> go build
.\api_pet.go:80:34: undefined: available
Steps to reproduce

A query parameter using a schema with default and oneOf:

      parameters:
        - name: status
          in: query
          description: Status value that needs to be considered for filter
          schema:
            default: "available"
            oneOf:
              - $ref: '#/components/schemas/StatusType'
Related issues/PRs

Issue introduced by #15126

Suggest a fix

I tried running the generation with defaultValue=false but that didn't stop the default value code from being generated:

java -jar .\openapi-generator-cli.jar generate -g go -o petstore-i petstore.yaml  --additional-properties="defaultValue=false" --package-name petstore -t C:\repos\openapi-generator\modules\openapi-generator\src\main\resources\go
wing328 commented 9 months ago
          schema:
            default: "available"
            oneOf:
              - $ref: '#/components/schemas/StatusType'

If you change oneOf to allOf, would that work?

AlanCitrix commented 9 months ago

Unfortunately that produces the same result. Here is the debug model:

    }, {
      "openApiType" : "interface{}",
      "baseName" : "status",
      "getter" : "GetStatus",
      "setter" : "setStatus",
      "dataType" : "interface{}",
      "datatypeWithEnum" : "interface{}",
      "name" : "Status",
      "defaultValueWithParam" : " = data.status;",
      "baseType" : "interface{}",
      "example" : "null",
      "jsonSchema" : "{\r\n  \"schema\" : {\r\n    \"type\" : \"string\",\r\n    \"enum\" : [ \"available\", \"pending\", \"sold\" ]\r\n  }\r\n}",
      "exclusiveMinimum" : false,
      "exclusiveMaximum" : false,
      "required" : false,
      "deprecated" : false,
      "hasMoreNonReadOnly" : false,
      "isPrimitiveType" : true,
      "isModel" : false,
      "isContainer" : false,
      "isString" : false,
      "isNumeric" : false,
      "isInteger" : false,
      "isShort" : false,
      "isLong" : false,
      "isUnboundedInteger" : false,
      "isNumber" : false,
      "isFloat" : false,
      "isDouble" : false,
      "isDecimal" : false,
      "isByteArray" : false,
      "isBinary" : false,
      "isFile" : false,
      "isBoolean" : false,
      "isDate" : false,
      "isDateTime" : false,
      "isUuid" : false,
      "isUri" : false,
      "isEmail" : false,
      "isPassword" : false,
      "isNull" : false,
      "isVoid" : false,
      "isFreeFormObject" : false,
      "isAnyType" : true,
      "isArray" : false,
      "isMap" : false,
      "isEnum" : false,
      "isInnerEnum" : false,
      "isEnumRef" : false,
      "isReadOnly" : false,
      "isWriteOnly" : false,
      "isNullable" : true,
      "isSelfReference" : false,
      "isCircularReference" : false,
      "isDiscriminator" : false,
      "isNew" : false,
      "vars" : [ ],
      "requiredVars" : [ ],
      "vendorExtensions" : {
        "schema" : {
          "type" : "string",
          "enum" : [ "available", "pending", "sold" ]
        },
        "x-golang-is-container" : true,
        "x-go-base-type" : "interface{}"
      },
      "hasValidation" : false,
      "isInherited" : false,
      "nameInCamelCase" : "status",
      "nameInSnakeCase" : "STATUS",
      "uniqueItems" : false,
      "isXmlAttribute" : false,
      "isXmlWrapped" : false,
      "additionalPropertiesIsAnyType" : false,
      "hasVars" : false,
      "hasRequired" : false,
      "hasDiscriminatorWithNonEmptyMapping" : false,
      "hasMultipleTypes" : false,
      "schemaIsFromAdditionalProperties" : false,
      "isBooleanSchemaTrue" : false,
      "isBooleanSchemaFalse" : false,
      "isEnumOrRef" : false,
      "hasItems" : false,
      "iexclusiveMaximum" : false,
      "datatype" : "interface{}"
    } ],
AlanCitrix commented 8 months ago

Actually my mistake, allOf did do the trick. There was another bug in the swagger which I've fixed in the first post. There was an extra schema in the enum. Thanks for the workaround.

components:
  schemas:
    StatusType:
      schema: // <--- removed this and changed to allOf, works now
        type: string
        enum:
          - available
          - pending
          - sold