OpenAPITools / OpenAPITools/openapi-generator
[REQ] [Java] [Spring] mixed OneOf support with JsonUnwrapped
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Is your feature request related to a problem? Please describe.
Support models with oneOf without discriminator combined with properties (or allOf)
For example:
components:
schemas:
Account:
type: object
properties:
owner:
type: string
bank:
$ref: '#/components/schemas/Bank'
oneOf:
- properties:
bankNumber:
type: string
bic:
type: string
- properties:
iban:
type: string
Describe the solution you'd like
Create an property annotated with @JsonUnwrapped
class Account {
String owner;
@JsonUnwrapped
BankWrapper oneOf;
}
In case of useOneOfInterfaces = false
Generate an class with the composition of the oneOf elements.
For example:
public class BankWrapper {
private String bankNumber;
private String bic;
private String iban;
}
In case of useOneOfInterfaces = true
Generate an wrapper interface for the oneOf elements using the appropriate JsonCreator static factory.
For example:
interface BankWrapper {
@JsonCreator
static BankWrapper(...) {
....
}
}
Describe alternatives you've considered
- Use composition for the oneOf by merging the elements (not very obvious generated classes)
- create a custom deserializer for Account (complex)
- create a normalizer to extract the oneOf and annotate with a vendorExtension
Additional context
Jackson ``@JsonUnwrapped` allows serialization of this json:
{
"owner": "John Doe",
"iban": "BE0001119990000"
}
Deserialization is more limited. Custom deserializer or @JsonSubTypes are not supported by @JsonUnwrapped
@JsonCreator static factory does work.
Arguments for @JsonCreator are limited to indivual @JsonProperty arguments, JsonNode or Map.
A JsonMapper configured with a Mixin allows the deserialization:
@JsonCreator
static AccountOneOfWrapper valueOf(JsonNode node) {
return MAPPER.treeToValue(node, AccountOneOfWrapper.class);
}
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(value = AccountOneOf.class),
@JsonSubTypes.Type(value = AccountOneOf1.class)
})
static interface AccountOneOfWrapperMixin {
}
mapper is:
MAPPER = JsonMapper.shared().rebuild()
.addMixIn(AccountOneOfWrapper.class, AccountOneOfWrapper.AccountOneOfWrapperMixin.class)
.build();
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No repository files or tests are named. Start by locating the Java/Spring generation paths for oneOf and existing JsonUnwrapped handling, then define coverage for both useOneOfInterfaces settings and verify generated Account/BankWrapper serialization and deserialization against the examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi, spring
- Domain
- backend-api-design, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100