swagger-api / swagger-api/swagger-core

Inconsistent behaviour for oneOf

Open
#4,352 1 comment 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

backlog
Dominant language
Java
Stars
7.5k
Forks
2.3k
Avg merge
18h 1m
Merged PRs (30d)
10

Description

When specifying in a @Schema the field oneOf alongside discriminatorMapping, in resulting OpenAPI specification all the properties of the parent are also copied in the children specified in oneOf.

Code example

@Schema(
    discriminatorProperty = "discriminator",
    discriminatorMapping = {
      @DiscriminatorMapping(
          value ="A",
          schema = A.class),
      @DiscriminatorMapping(
          value = "B",
          schema = B.class)
    },
    oneOf = {
      A.class,
      B.class,
    })
public abstract class Parent {
  
    @Schema(name = "discriminator")
    public String discriminator;
  
   @Schema(name = "test")
    public int test;
}

@Schema
public class A extends Parent {
    @Schema(name = "testA")
    public int testA;
}

@Schema
public class B extends Parent {
    @Schema(name = "testB")
    public int testB;
}

Resulting OpenAPI spec:

Parent:
   type: object
   oneOf:
   - $ref: '#/components/schemas/A'
   - $ref: '#/components/schemas/B'
   discriminator:
      mapping:
         A: '#/components/schemas/A'
         B: '#/components/schemas/B'
        propertyName: providerName
   properties:
      discriminator:
         type: string
      test:
         type: string
A:
   type: object
   allOf:
   - $ref: '#/components/schemas/Parent'
   - type: object
     properties:
        testA:
           type: string
B:
   type: object
   allOf:
   - $ref: '#/components/schemas/Parent'
   - type: object
     properties:
        testB:
           type: string

But when specifying in a @Schema the field oneOf without discriminatorMapping, the children specified in the oneOf have an allOf property with a references to the parent.

Code example (same as above, but without the discriminator)

@Schema(
    oneOf = {
      A.class,
      B.class,
    })
public abstract class Parent {
  
    @Schema(name = "discriminator")
    public String discriminator;
  
   @Schema(name = "test")
    public String test;
}

@Schema
public class A extends Parent {
    @Schema(name = "testA")
    public String testA;
}

@Schema
public class B extends Parent {
    @Schema(name = "testB")
    public String testB;
}

Resulting OpenAPI spec:

Parent:
   type: object
   properties:
      discriminator:
         type: string
      test:
         type: string
A:
   type: object
   properties:
      discriminator:
         type: string
      test:
         type: string
      testA:
         type: string
B:
   type: object
   properties:
      discriminator:
         type: string
      test:
         type: string
      testB:
         type: string

This seems a bit like an inconsistent behaviour. I was wondering if this was intended or if I am missing something?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing how @Schema oneOf, discriminatorMapping, and Java inheritance are converted into the generated OpenAPI schemas. Compare the two examples, with and without discriminatorMapping, and inspect existing schema-generation tests if available. Done means the inheritance behavior is made consistent with the intended OpenAPI output and covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.