yonaskolb / SwagGen

OpenAPI/Swagger 3.0 Parser and Swift code generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nullable support?

raphaeloliveira opened this issue · comments

Hey Yonas, I'm curious if SwagGen currently supports the nullable attribute as described in the Swagger docs. Apparently a required property with nullable: true is not correctly mapped to an optional property on Swift.

Example:

type: object
      required:
        - name
      properties:
        name:
          description: User name
          type: string
          nullable: true

I started my investigation on Model.stencil:

public {% if options.mutableModels %}var{% else %}let{% endif %} {{ property.name }}: {{ property.optionalType }}

which led me to

public struct Property {
    public let name: String
    public let required: Bool
    public let schema: Schema
}

which indeed doesn't seem to have a nullable field.

I'm curious if the fix would be to update ObjectSchema initialiser

public init(jsonDictionary: JSONDictionary) throws {
        let requiredPropertyNames: [String] = (jsonDictionary.json(atKeyPath: "required")) ?? []
        let propertiesByName: [String: Schema] = (jsonDictionary.json(atKeyPath: "properties")) ?? [:]

        requiredProperties = requiredPropertyNames.compactMap { name in
            if let schema = propertiesByName[name] {
                return Property(name: name, required: true, schema: schema)
            }
            return nil
        }
        ....

and only add the property on the requiredProperties array if nullable is false.

Is that the right direction?

Expanding further, in my opinion the optional type should be mapped like this:

required nullable Type
false false Optional
false true Optional
true false Non Optional
true true Optional

This should also work seamlessly with decodeIfPresent, which returns nil in the absence of the key or the key with value null.

Hi @raphaeloliveira.
Yes some updates would be to be made to support this properly.
nullable already exists on schema.metadata at the moment. In Swagger 2.0 it was called x-nullable though so the decoder needs to be updated here https://github.com/yonaskolb/SwagGen/blob/master/Sources/Swagger/Metadata.swift#L36 to something like

nullable = jsonDictionary.json(atKeyPath: "nullable") ?? jsonDictionary.json(atKeyPath: "x-nullable") ?? false

Then the optional and optionalType context properties would need to read from that in the way you suggested

!property.required || property.metadata.nullable

both here and here
The parameter context could also be updated if the type is a schema.

If you could create a PR that would be great 😄👍

Hey @yonaskolb, here is the PR #165.

I tested by installing my local branch swaggen version using make install and generating code using a spec that used the nullable attribute - all seemed to work fine.

Is there something else that needs to be done? Bumping version or something like that?

Thanks for that @raphaeloliveira.
Once that is merged a release needs to be manually made. You could also point to master in your MintFile until then