CreateAPI: `enum` unknown values
Forced unknown
Since we are creating API interfaces, new cases may be created from the server that aren’t available on a current version of a developer’s SDK or even their available schema. Only Apple can create nonfrozen enums by my understanding so developers cannot use @unknown default
. So, if an app with an out-of-date API schema attempts to decode an unknown case for a property or return type that cannot be optional, it will crash.
To fix this issue, create a new config option enumForceUnknown: true
that adds a new case to every enum which represents an unknown case. We would decode to this unknown case if there is no properly expected case currently defined. The name is open for improvement, but I think that it should stand out from typical Swift formatting in a way that ensures it will be different from any case in the schema and tells the developer that this is strongly unknown.
enum MyTypes {
case foo
case bar
case forced_unknown // added unknown case
}
Organization
Smaller pitch for an organization option to put enum
s in a separate folder: Enums
. Just as an organizational measure this can help a lot to separate the struct/class
entities from other Swift types to the developer. This would only apply to the split generation and remain as an option. Or, could also apply to merged generation with a separate Enums.swift
file.
MyAPI
- Entities/
- Paths/
- Enums/
AnyJson.swift
Potentially split generation might have more customization options, so we create a new section in the config for each generation type. This would help with https://github.com/CreateAPI/CreateAPI/issues/47.
split:
- enumFolder: true
// other options
There would also be a separate section for merged
with whatever options it would potentially have. The existence of these two sections together would throw an incorrect config error. This was just a loose idea, needs much improvement.
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 1
- Comments: 16 (13 by maintainers)
Sensible to me
It feels like it would make sense to incorporate
enums
undergenerate
regardless to if we bring in more options or not actually. I’ll probably go ahead and do that in my change anyway unless there is a good reason not to?I see value now in creating the extensions from a
RawRepresentable
. That sounds good 👍Any vendor can compile their library using Library evolution using
BUILD_LIBRARY_FOR_DISTRIBUTION
(although I’m not sure how to do this with swift packages).Using such library would mean that by default any
enum
within that module will be treated as unfrozen which would require the@unknown default
statement in switch cases unless the enum was annotated with@frozen
.But then again, it’s probably unlikely that anybody is ever going to use library evolution.
This to be honest sounds like a problem outside of CreateAPI because the API being consumed isn’t being versioned properly. The JSON Schema/OpenAPI specification does not support any differentiation between frozen or unfrozen enums and technically when you are using a different schema, it should be versioned differently.
We have this discussion a lot in my company and make it clear to api engineers that enums should be considered frozen for the current API version so adding cases is considered a breaking change.
That being said, if we really did want to support flexibility then instead I recommend generating
RawRepresentable
structs instead of enums. For example:would become this:
The
generateEnums
option could instead become something likeenumDecoration
with accepted values ofnone
,enum
andrawRepresentable
. Maybe we could come up with something better, but something along those lines.