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.72k stars 6.55k forks source link

[SWIFT4] Request does not conform to protocol 'Decodable' #925

Open Parilar opened 6 years ago

Parilar commented 6 years ago
Description

Every request got the error "Type 'MyRequestRequest' does not conform to protocol 'Decodable'"

openapi-generator version

3.2.2

Command line used for generation

openapi-generator generate - swagger.json -g swift4 -o api

Using Xcode 10 and Newest Swift version

Parilar commented 6 years ago

Problem solved. The solution was that the API got some mistakes. When an Request defines his params as object : "properties": { "params": { "type": "object" }, the API generates code which is not Codeable. public var params: Any

defining an object and referencing it in the request solved the problem

jacobweber commented 5 years ago

I think this should be re-opened. My understanding is that Swagger spec allows free-form objects using type: object.

allezxandre commented 4 years ago

Any pointers to how we should handle type: objects instances?

I haven't tried it yet but I was thinking maybe the generator could use Codable instead of Any?

cerupcat commented 4 years ago

Any updates on this? It looks like using Any anywhere on an object breaks building since it's not Codable.

lou-lan commented 4 years ago

Any updates on this? I have the same problem.

wing328 commented 4 years ago

Instead of Any, what should be a proper type in Swift to map type: object?

lou-lan commented 4 years ago

Hi. This is the Kubernetes api document definition. Value can be int-or-string.

"v1.RollingUpdateDaemonSet": {
    "description": "Spec to control the desired behavior of daemon set rolling update.",
    "properties": {
    "maxUnavailable": {
        "description": "",
        "format": "int-or-string",
        "type": "object"
    }
    },
    "type": "object"
},
wing328 commented 4 years ago

I'm aware of such definition in Kubernetes as I was involved in the client generation for the Kubernetes API before.

If I remember correctly, it's using OpenAPI v2 to describe the API. In the long term, better upgrade to OpenAPI v3 and use oneOf to describe such property, e.g.

oneOf:
  - type: string
  - type: integer

In Swift, what type would be the best to store something that can be either a string or integer?

lou-lan commented 4 years ago

So that's it, thank you very much for your answer. Kubernetes is written in the go language, and there is no mature implementation of openapi v3 in go, so upgrading from v2 to v3 would be a big project. But it does need to be addressed from the Kubernetes side.

wing328 commented 4 years ago

What about mapping type: object as a String in Swift for the time being as everything can be represented as a string and developers and convert the string into whatever type that's appropriate and the auto-generated Swift will at least compile?

You can test this workaround/solution using the typeMapping option for the time being: https://openapi-generator.tech/docs/usage/#type-mappings-and-import-mappings

robmaceachern commented 3 years ago

I'm hitting this issue too.

FYI @wing328 swagger-codegen maps object to a custom JSONObject type. I think that makes sense.

Another option would be to erase the type information with a wrapper type (e.g. AnyCodable) but I prefer a JSONObject type for this situation.

wing328 commented 3 years ago

FYI @wing328 swagger-codegen maps object to a custom JSONObject type. I think that makes sense.

That's one way to do it (but what if the payload is not JSON (technically it can be XML or something else but from what I know the Swift generator only supports JSON payload at the moment)

wing328 commented 3 years ago

cc Swift technical committee to see if they've a different opinion on this.

@jgavris (2017/07) @ehyche (2017/08) @Edubits (2017/09) @jaz-ah (2017/09) @4brunu (2019/11)

4brunu commented 3 years ago

I think using the JSONObject would do it, and it's a better solution than the one we have now. Looking into the future, supporting oneOf with an enum generated for each response, would be nice.

robmaceachern commented 3 years ago

technically it can be XML or something else but from what I know the Swift generator only supports JSON payload at the moment

Yeah I guess technically we'd need to look at the contentType of the object and only map to JSONObject if it is application/json.