question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New `union` json strategy to generate discriminated unions

See original GitHub issue

Defining tagged union in smithy produces pure unions when compiled into openapi (json-schema) by the smithy plugin. This means the generated api definition is not satisfactory.

Example in smithy:

union U {
    optionA : OptionA,
    optionB : OptionB
}
structure OptionA { a : String }
structure OptionB { b : String }

translate into a json shema which will allow OneOf 2 objects (with the OneOf strategy which is the default):

{ "optionA" : { "a" : "some user string" } }

or

{ "optionB" : { "b" : "some user string" } }

Forcing the receiving end to guess the type from the awkward top-level member name.

OpenAPI and recent json schema allow discriminated unions (tagged union with the tag being called inside the objects as “discriminators”) where one would end up with accepted objects:

{ "kind" : "optionA", "a" : "some user string" }

or

{ "kind" : "optionB", "b" : "some user string" }

“kind” is the discriminator field here, note there is no requirement on its name and could be anything (common ones are “discriminator”, “type”, etc).

One could think about using a default discriminator name like “kind”, or allow it to be defined in smithy:

@discriminator("kind")
union U {
    optionA : OptionA,
    optionB : OptionB
}
structure OptionA { a : String }
structure OptionB { b : String }

Having a field automatically added to the OptionA and OptionB might not be very smithy like? A possibility if we can define constant fields would be something like:

@discriminator("kind")
union U {
    optionA : OptionA,
    optionB : OptionB
}
structure OptionA {
  @constant("OptionA")
  kind: String,
  a : String
}
structure OptionB {
  @constant("OptionB")
  kind: String,
  b : String
}

Where smithy validation would check that the discriminator is defined in all the option shapes and that it is a constant.

Refs: https://github.com/awslabs/smithy/blob/17d912e7fa84069b58072cc935f37412a8bddd16/docs/source/1.0/guides/converting-to-openapi.rst https://github.com/awslabs/smithy/blob/75928a7c69b2a156382b5d8bc87a6991f5fea64e/smithy-jsonschema/src/main/java/software/amazon/smithy/jsonschema/JsonSchemaShapeVisitor.java#L227

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:4
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
adamthom-amzncommented, Mar 11, 2022

How unions are serialized on the wire is protocol-specific; even if the OpenAPI specification included a discriminator, restJson1 clients and servers would not serialize it. We don’t have a protocol defined at the moment that would support this.

Language-specific codegen can decide to offer a discriminator field if that makes sense for the language in question; this is independent of how it is serialized in the wire and appears in OpenAPI. If this is something you believe would be more idiomatic for a specific language, I think it’d be fair to open a feature request for the language-specific repository in question where the discussion can be furthered in the context of that language.

1reaction
eduardomourarcommented, Feb 28, 2022

Could this issue be reopened, please? We are running into the same problem state here, and a solution would be nice even if only for language specific generators.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Discriminated Unions and Dapper | codesuji
What options do I have. One way is to treat this simple discriminated union by mapping it's underlying values to string values (e.g....
Read more >
Mimic Discriminated Union Types in C# with serialization via ...
Now we can implement a JSON converter that will be aware of union types. We also make this converter work with generic classes....
Read more >
Importing JSON into interface with discriminated unions
I have a problem with importing json into interface with discriminated union pattern used. The error message I get on the assignment of ......
Read more >
Union Types, Discriminated Unions, and Type Guards
When unions are applied over primitives and literals, the union is exclusive, meaning the value being assigned to the union type cannot be...
Read more >
Discriminated Unions or Tagged Unions Types - YouTube
The fourth video in our TypeScript Narrowing series. In this video, we cover Tagged Union Types (also known as Discriminated Unions ).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found