gen: discriminator property is removed from structures
The discriminator field is removed from the generated structs. Suppose some API endpoint accepts a String and not a TypeDef and it expects to receive the kind property. Currently, the generated API client can not call such an endpoint since it wont be including the discriminator field. There could also be cases where the value of the discriminator property is useful for other things than deciding the type. Should it not always be included in the types? Especially if I manually put it as a required field like in the example below.
What version of ogen are you using?
$ go list -m github.com/ogen-go/ogen
github.com/ogen-go/ogen v0.81.0
Can this issue be reproduced with the latest version?
Yes
What did you do?
TypeDef:
oneOf:
- $ref: '#/components/types/String'
- $ref: '#/components/types/Int'
discriminator:
propertyName: kind
mapping:
string: '#/components/types/String'
int: '#/components/types/Int'
String:
type: object
required:
- kind
properties:
kind:
type: string
Int:
type: object
required:
- kind
properties:
kind:
type: string
What did you expect to see?
// Ref: #/components/types/String
type String struct{
Kind string `json:"kind"`
}
// Ref: #/components/types/Int
type Int struct{
Kind string `json:"kind"`
}
What did you see instead?
// Ref: #/components/types/String
type String struct{}
// Ref: #/components/types/Int
type Int struct{}
@johanhenriksson did you find a workaround for this issue?
The only thing I've found it to define a kind of type alias to use in oneOf schema, e.g.
StringForDiscriminator:
allOf:
- $ref: '#/components/types/String'
- type: object
properties:
kind:
type: string
In that case we have 2 objects generated, one to be used in the case with discriminator, and another one without. But it looks a bit ugly, tbh. Another solution is to just define a map and put data there
additionalProperties:
type: string
So having following schema
openapi: 3.0.3
info:
title: Discriminator example
description: Example
version: 1.0.0
paths:
/example:
get:
responses:
200:
description: OK
content:
"application/json":
schema:
$ref: '#/components/schemas/Response'
components:
schemas:
Alpha:
type: object
required:
- kind
- variant
- data
properties:
kind:
type: string
variant:
type: string
data:
type: string
Beta:
type: object
required:
- kind
- variant
- value
properties:
kind:
type: string
variant:
type: string
value:
type: string
SumAuto:
oneOf:
- $ref: '#/components/schemas/Alpha'
- $ref: '#/components/schemas/Beta'
SumFirst:
discriminator:
propertyName: kind
mapping:
alpha: '#/components/schemas/Alpha'
beta: '#/components/schemas/Beta'
oneOf:
- $ref: '#/components/schemas/Alpha'
- $ref: '#/components/schemas/Beta'
SumSecond:
discriminator:
propertyName: variant
mapping:
a: '#/components/schemas/Alpha'
b: '#/components/schemas/Beta'
oneOf:
- $ref: '#/components/schemas/Alpha'
- $ref: '#/components/schemas/Beta'
Response:
type: object
required:
- Auto
- First
- Second
- Alpha
- Beta
properties:
Auto:
$ref: '#/components/schemas/SumAuto'
First:
$ref: '#/components/schemas/SumFirst'
Second:
$ref: '#/components/schemas/SumSecond'
Alpha:
$ref: '#/components/schemas/Alpha'
Beta:
$ref: '#/components/schemas/Beta'
Discriminator properties are removed from Alpha and Beta, but should not.
@tdakkota please take a look.
@vkuptcov I have not found a good workaround to this, no. We managed to do without it, but having the discriminator field on the generated types would make life easier.