-
Notifications
You must be signed in to change notification settings - Fork 239
Open enum union proposal #2787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
msosnicki
wants to merge
3
commits into
smithy-lang:main
Choose a base branch
from
msosnicki:open-enum-union-proposal
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Open enum union proposal #2787
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Enums and unions allowed to be closed | ||
|
||
## Abstract | ||
|
||
In the Smithy 2.0 specification enums and unions are treated as strictly **open**: adding a member is always treated as a backward‑compatible change and clients are expected to handle unknown members at runtime. This RFC proposes to update the spec and loosen the strict requirements around open enums and unions, acknowledging the fact that for some use cases and protocols it may not be desireable. It will also align the spec closer to reality, as smithy4s do not follow the current spec. | ||
|
||
## Motivation | ||
|
||
It has been identified by smithy users that **open by default** enums and unions might be problematic for several reasons: | ||
|
||
- **Exhaustiveness and type safety**. Many target languages (like Scala) encourage type safety and exhaustive matches on enums and algebraic data types. Default open enums/unions forces default, catch-all branches, weakening compiler checks and forcing implementations to either provide a catch-all default (see points below for issues with it) or weaken exhaustivity of the union encoding. | ||
- **Data integrity**. Treating unexpected variants as acceptable can mask producer errors and defer the discovery of such bugs. Closed enums and unions force modelers to be explicit if they want to opt-in and make it open for cases where forward compatibility is truly required. | ||
- **Protocol‑agnostic friction** - Unknown members of open unions are inherently protocol‑specific (e.g., JSON or binary) - it’s difficult to guarantee a single, portable “unknown” representation across protocols and therefore strictly follow the current spec. | ||
- **Explicitness**: Unexpected variants can become explicit design decisions enabled on a per protocol basis. | ||
|
||
At the same time, open unions are valuable in certain domains - for example, event streams that evolve by adding event types. | ||
|
||
## Proposal | ||
|
||
* The strict requirements for open enums and unions are loosened. | ||
* Protocol level opt-ins are outside of the scope of what the `smithy.api` would provide. | ||
|
||
## Smithy4s example | ||
|
||
[Smithy4s](https://disneystreaming.github.io/smithy4s/) chooses to model unions and enums as closed by default. Below a quick summary of how it achieves the opt-in openness. | ||
|
||
### Enums | ||
|
||
Enums are closed by default, but [as an opt-in](https://disneystreaming.github.io/smithy4s/docs/codegen/customisation/open-enums) can be opened. This is done via custom trait, `alloy#openEnum`: | ||
|
||
```smithy | ||
use alloy#openEnum | ||
|
||
@openEnum | ||
enum Shape { | ||
SQUARE, CIRCLE | ||
} | ||
|
||
@openEnum | ||
intEnum IntShape { | ||
SQUARE = 1 | ||
CIRCLE = 2 | ||
} | ||
|
||
``` | ||
|
||
Presence of such annotation will cause the codegen also generate an `Unknown` variant, capable of capturing the values which do not match to the set of known enum cases. | ||
|
||
### Unions | ||
|
||
Unions are also closed by default and like enums can be [opened](https://disneystreaming.github.io/smithy4s/docs/codegen/unions/#open-unions). Smithy4s outputs protocol agnostic code, and it would not be easy to provide a single “unknown” representation that works well across protocols. | ||
|
||
In the context of the json based protocols, unions can be opened, like so: | ||
|
||
```smithy | ||
use alloy#jsonUnknown | ||
|
||
union Shape { | ||
square: Square | ||
@jsonUnknown other: Document | ||
} | ||
|
||
structure Square { | ||
@required side: Integer | ||
} | ||
``` | ||
|
||
Such addition will make encoders and decoders aware about the unknown member - for example when deserializing an unknown variant, the whole json node (including a discriminator or tag) will be captured into such a `Document`. | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently the
smithy-trait-codegen
also do not follow the spec, see here