apple / swift-openapi-generator

Generate Swift client and server code from an OpenAPI document.
https://swiftpackageindex.com/apple/swift-openapi-generator/documentation
Apache License 2.0
1.43k stars 116 forks source link

Create a URI encoder and decoder that works with Codable types #192

Closed czechboy0 closed 1 year ago

czechboy0 commented 1 year ago

Create a URI encoder and decoder that works with Codable types.

More details in this comment: https://github.com/apple/swift-openapi-generator/issues/182#issuecomment-1675870562

bfrearson commented 1 year ago

This is definitely needed, but before we continue it would be good to reach a consensus on what we should do with a nested type such as:

struct NestedType: Encodable {
    let name: String
    let ship: Ship
}

struct Ship: Encodable {
    let designation: String
    let crew: [String]
    let type: String
}

The expected output of our encoder, I assume, would always be key-value pairs in the form key1=value1&key2=value2. There is nothing in the openapi spec that prevents a schema like the example above from being used here, even though it doesn't match the architecture, so we need to have a way of handling this, even if it is bad practice.

There's multiple ways that we could handle these types, and in the long run it would be good to support a few different methods. However, I think for the moment, we should decide on a single implementation and expand from there.

What should the output of our encoder look like for a type that itself contains other Codable types like the example above (percent encoding omitted for clarity)?

For the very short term, I'd suggest we error out until the initial encoder is written, but I imagine that's not acceptable in the longer run.

czechboy0 commented 1 year ago

I'd like us to support any arbitrarily nested Codable type, as it's not going to be that much more work than just top level items. I have a design in mind, let me try to put together a prototype end of this or next week and we can take it from there.

czechboy0 commented 1 year ago

Early encoder prototype I'm working on: https://github.com/apple/swift-openapi-runtime/pull/41

czechboy0 commented 1 year ago

So, after actually reading the 6570 and 1866 RFCs, turns out nesting containers is not a supported feature. All the nesting approaches seem to be conventions that people invented on top.

The first implementation of URIEncoder/URIDecoder will not support nesting containers, but I'd be open to enhancing it in the future to support nesting, assuming we can have some confidence that what we implement is actually used widely.

bfrearson commented 1 year ago

I think this is a reasonable stance. Any well formed api will adhere to the standards, and users in need of a more complex data structure should probably be using json instead.

The only pain point is that the open api spec explicitly doesn't enforce this conformance, so it's possible to define an openapi document that will try to use a nested object. What's the error state if we try and do this? Should the generator fail with an error here?

czechboy0 commented 1 year ago

The URI coder itself will fail at runtime with a descriptive error. I'm afraid detecting this in the generator might be a lot of work and doesn't bring much value. Users won't get this working anyway.