CreateAPI / CreateAPI/CreateAPI

Provide a way to safe decode collection items

Open
#18 6 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Swift
Stars
447
Forks
42
PR merge metrics
No merged PRs in 30d

Description

hey,

some other open api generator tools provide a way to generate code that safely decodes elements of an array and ignore the ones that don't. This can be used in scenarios where new types are likely to be introduced in the API and yet we don't want older api clients not supporting the new types to break.

For instance, [Swaggen](https://github.com/yonaskolb/SwagGen) can decode all arrays using the [`decodeArray`](https://github.com/yonaskolb/SwagGen/blob/master/Templates/Swift/Sources/Coding.swift#L125-L152) which ignores elements that fail to decode.

While this works, having such a global setting which simply ignores elements of all arrays is a big assumption that should not be part of the code generation library imo: there are cases where we want some types to be decoded safely and some cases where we want them to be more strict.

I was wondering if and how CreateAPI could provide a similar functionality while remaining flexible enough.

My thoughts are that it should be up to the user of CreateAPI to
- Decide what are the collections that can have elements which can be decoded in a safe manner.
- What to do if an element fails to decode.

For this purpose, in our **non generated** code (that I'm trying to migrate to a generated code), we use a custom type to wrap the entities that are likely to fail. For instance, the following `Throwable` simply logs the decoding error

```swift
public struct Throwable: Decodable {
let result: Result

public init(from decoder: Decoder) throws {
do {
result = .success(try T(from: decoder))
} catch let error {
logger.info("Failed to decode: \(error)")
result = .failure(ThrowableDecodableError())
}
}

public func get() -> T? {
return try? result.get()
}
}
```

We then declare the collections properties like this

```swift
public struct Store: Decodable {
public let pets: [Throwable]
}
```

Introducing the above `Throwable` in CreateAPI would be again too much assumption and that's not what I'm proposing here. It's just for illustration.

However, I was thinking if it would make sense to create a setting such as `arrayTypeWrappers`

```yaml
arrayTypeWrappers: [
"MyEntity": "MySettingType"
]
```
which would be a mapping of types that CreateAPI would use to simply output `[MySettingType]` instead of
`[MyEntity]`.

So back to my `Throwable` example, a setting
```yaml
entities:
arrayTypeWrappers: [
"Pet": "Throwable"
]
```

would generate

```swift

public struct Store: Decodable {
public let pets: [Throwable]
}

public struct World: Decodable {
public let stores: [Store] // nothing new here
}
```

Of course, the user of CreateAPI would have to provide the `Throwable` implementation for the code to compile

Any thoughts?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.