microsoft / microsoft/typespec

Add @anyOf decorator for discriminated unions in OpenAPI emitter

Open
#7,857 4 comments 0 reactions 0 assignees View on GitHub
emitter:json-schema feature triaged:core
Dominant language
Java
Stars
5.9k
Forks
394
Avg merge
1d 23h
Merged PRs (30d)
104

Description

## Problem
When using `@discriminated` with a union in TypeSpec, the OpenAPI emitter always generates `oneOf`:

```typespec
@discriminated(#{envelope: "none"})
union Foo {
a: Bar;
b: Bar;
}
```

This emits:
```yaml
Foo:
type: object
oneOf: # Always oneOf with discriminator
- $ref: '#/components/schemas/Bar'
- $ref: '#/components/schemas/Bar'
discriminator:
propertyName: kind
mapping:
a: '#/components/schemas/Bar'
b: '#/components/schemas/Bar'
```

## Issue
- No way to force `anyOf` for discriminated unions (unlike `@oneOf` for non-discriminated unions) despite this being legal and semantically the same
- https://github.com/OAI/OpenAPI-Specification/blob/3.0.3/versions/3.0.3.md#fixed-fields-21
- Some openapi tools (like NSwag) only correctly parse discriminators with `anyOf`
- Default behavior should be _documented_ (given documentation currently suggests it should be anyOf by default)
- Behaviour should be configurable

## Proposed Solution
Add `@anyOf` decorator to allow explicit `anyOf` generation for discriminated unions:

```typespec
@discriminated(#{envelope: "none"})
@anyOf
union Foo {
a: Bar;
b: Bar;
}
```

## Related
- OpenAPI spec allows discriminators with both `oneOf` and `anyOf`
- NSwag issue: https://github.com/RicoSuter/NJsonSchema/issues/13
- Discussed with @timotheeguerin and @bterlson in TypeSpec Discord

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.