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
21.81k stars 6.58k forks source link

[BUG] [Go] The nullable property value has no effect to ref #3159

Open alex-korobko opened 5 years ago

alex-korobko commented 5 years ago

Bug Report Checklist

Description

There are no pointers generated for the references with nulllable: true.

openapi-generator version

The latest Docker image. I tried Docker images tagged as v4.0.0 and v4.0.1 as well.

OpenAPI declaration file content or url

Here is the Gist I created to reproduce the issue : https://gist.github.com/alex-korobko/e5029d746e3c5631af9ab43319761d0f

openapi: 3.0.1
info:
  version: 1.0.0
  title: Test spec
  description: Trying to find out if nullable affects output for refs in code generation for Go
  contact:
    name: Alex Korobko
    email: korobko.alex@gmail.com
servers:
  - url: https://my.cool.server.com/api/v1
paths:
  /GetHealthCheck:
    get:
      summary: Health check endpoint
      responses:
        200:
          description: Returns successful result if the instance started successfully
          content:
            application/json:
              schema:
                type: object
                $ref: '#/components/schemas/HealthCheckResult'
components:
  schemas:
    HealthCheckResult:
      type: object
      properties:
        NullableRefProperty:
          nullable: true
          description: Just an object that could be null
          $ref: '#/components/schemas/NullableRef'
        NullableObjProperty:
          type: object
          nullable: true
          description: Nullable object directly in spec
          properties:
              NullableName:
                type: string
                nullable: true
                description: Nullable property in object
    NullableRef:
      type: object
      properties:
        Name:
          type: string
          nullable: true
          description: Just a name to test in nullable ref
Command line used for generation

I used the following generation parameters:

docker run  \
        --volumes-from spec-image \
        openapitools/openapi-generator-cli:latest generate \
        -t /$DOCKER_VOLUME_NAME/ \
        -g go \
        -i /$DOCKER_VOLUME_NAME/spec.yaml \
        -DdebugModels \
        -DdebugOperations \
        -DenablePostProcessFile=true \
        -Dmodels \
        -DmodelDocs=false\
        -DpackageName=models\
        -o /$DOCKER_VOLUME_NAME/$GENERATE_DIR
Steps to reproduce

Use the spec and generate the models using the command line I provided. The NullableRefProperty property is not generated as a pointer:

/*
 * Test spec
 *
 * Trying to find out if nullable affects output for refs in code generation for Go
 *
 * API version: 1.0.0
 * Contact: korobko.alex@gmail.com
 * Generated by: OpenAPI Generator (https://openapi-generator.tech)
 */

package models

type HealthCheckResult struct {
    NullableRefProperty NullableRef `json:"NullableRefProperty,omitempty"`
    NullableObjProperty *HealthCheckResultNullableObjProperty `json:"NullableObjProperty,omitempty"`
}

It looks like there is no generation for the reference property NullableRefProperty despite the fact that the property do have the nullable: true in spec:

  NullableRefProperty:
          nullable: true

In the debug output produced when the debugModels flag is set it shows that the isNullable property is not set for the NullableRefProperty values :

    "vars" : [ {
      "openApiType" : "NullableRef",
      "baseName" : "NullableRefProperty",
      "complexType" : "NullableRef",
      "getter" : "getNullableRefProperty",
      "setter" : "setNullableRefProperty",
      "dataType" : "NullableRef",
      "datatypeWithEnum" : "NullableRef",
      "name" : "NullableRefProperty",
      "defaultValueWithParam" : " = data.NullableRefProperty;",
      "baseType" : "NullableRef",
      "example" : "null",
      "jsonSchema" : "{\n  \"$ref\" : \"#/components/schemas/NullableRef\"\n}",
      "exclusiveMinimum" : false,
      "exclusiveMaximum" : false,
      "hasMore" : true,
      "required" : false,
      "secondaryParam" : false,
      "hasMoreNonReadOnly" : false,
      "isPrimitiveType" : false,
      "isModel" : true,
      "isContainer" : false,
      "isString" : false,
      "isNumeric" : false,
      "isInteger" : false,
      "isLong" : false,
      "isNumber" : false,
      "isFloat" : false,
      "isDouble" : false,
      "isByteArray" : false,
      "isBinary" : false,
      "isFile" : false,
      "isBoolean" : false,
      "isDate" : false,
      "isDateTime" : false,
      "isUuid" : false,
      "isUri" : false,
      "isEmail" : false,
      "isFreeFormObject" : false,
      "isListContainer" : false,
      "isMapContainer" : false,
      "isEnum" : false,
      "isReadOnly" : false,
      "isWriteOnly" : false,
      "isNullable" : false,
      "isSelfReference" : false,
      "vendorExtensions" : { },
      "hasValidation" : false,
      "isInherited" : false,
      "nameInCamelCase" : "NullableRefProperty",
      "nameInSnakeCase" : "NULLABLE_REF_PROPERTY",
      "isXmlAttribute" : false,
      "isXmlWrapped" : false,
      "datatype" : "NullableRef",
      "iexclusiveMaximum" : false
    },
Related issues/PRs

The issue is different from https://github.com/OpenAPITools/openapi-generator/issues/2119 , the inline defined objects are got generated with references if nullable is set to true (see the spec for details)

Suggest a fix

I'd be glad to help fixing the issue, I have some experience in Java programming that is used to write the parser if I'm not mistaking. I assume the issue happens during the parsing the spec, as the variable properties that sent to the code generator already have "isNullable" : false, despite the fact that in spec the NullableRefProperty property has nullable: true property set. It would be great if you guys provide me some initial guidance where to start in code.

wing328 commented 5 years ago

@alex-korobko thanks for reporting the issue and offering help to fix it.

I found the following in the mustache template:

modules/openapi-generator/src/main/resources/go/model.mustache: {{name}} {{#isNullable}}*{{/isNullable}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`

so it seems like nullable is supported but not working somehow for nullable model.

Can you test with nullable string or integer instead to see if that works? If it works, we can isolate the problem to nullable model only.

alex-korobko commented 5 years ago

@wing328 Sorry for the late response.

As I understand (I could be wrong) the mustache file is applied after the models are generated. And I see in the debugModels output that isNullable flag is set to false. So in this case the mustache file has nо effect.

I.e. despite the fact that in spec I defined NullableRefProperty as nullable: true

NullableRefProperty:
          nullable: true
          description: Just an object that could be null
          $ref: '#/components/schemas/NullableRef'

The output of debugModels (see my comment above for details) flag shows that isNullable for the NullableRefProperty is returned as false

"isNullable" : false,

and therefore

modules/openapi-generator/src/main/resources/go/model.mustache: {{name}} {{#isNullable}}*{{/isNullable}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`

is not applied.

alex-korobko commented 5 years ago

Any update on that, guys?

stevenvdr commented 4 years ago

I think the generator is looking at the referenced definition to assign the nullable property (https://github.com/ackintosh/openapi-generator-1/blob/10e42461f5099d6c63e4592299f1baca93711f12/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java#L2248)

Workaround that works for me is by defining the referenced definition as nullable: eg in the example

    NullableRef:
      type: object
      nullable: true
      properties:
        Name:
          type: string
          nullable: true
          description: Just a name to test in nullable ref
aqemi commented 4 years ago

@stevenvdr Won't work in the case when referenced definition used in multiple places, with and without nullable.

monktastic commented 3 years ago

It seems this is somehow related to https://github.com/OAI/OpenAPI-Specification/issues/1368?

Unfortunately, the following workaround does not work here:

  "properties": {
    "name": { "type": "string" },
    "dataFork": { "$ref": "#/components/schemas/Fork" },
    "resourceFork": {
      "nullable": true,
      "anyOf": [ { "$ref": "#/components/schemas/Fork" } ] 
    },