swagger-api / swagger-parser

Swagger Spec to Java POJOs
http://swagger.io
Apache License 2.0
773 stars 525 forks source link

resolveFully together with allOf looses required properties #2081

Closed david0 closed 1 month ago

david0 commented 2 months ago

We are trying to enforce some properties via required together with allOf to reuse existing definitions:

openapi: 3.0.0
info:
  title: Minimal OpenAPI 3.0 with required on the same allOf
  version: 1.0.0
paths:
  /pets:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PetCreate'
      responses:
        '201':
          description: Created
components:
  schemas:
    Pet:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string

    PetCreate:
      allOf:
        - $ref: '#/components/schemas/Pet'
      required:
        - name

But using setResolveFully(true), the required attribute will get lost:

    @Test
    public void requiredAllResolveFully() {
        ParseOptions options = new ParseOptions();
        options.setResolveFully(true);
        OpenAPI openAPI = new OpenAPIV3Parser().read("required-anyOf.yaml", null, options);

        RequestBody requestBody = openAPI.getPaths().get("/pets").getPost().getRequestBody();
        Schema requestBodySchema = requestBody.getContent().get("application/json").getSchema();
        assertNull(requestBodySchema.get$ref()); // has been inlined

        Schema schema = requestBody.getContent().get("application/json").getSchema();
        assertEquals(schema.getProperties().size(),2);
        assertEquals(schema.getRequired().size(),1); // <-- FAILS, as its empty
    }
david0 commented 2 months ago

Another variation of this bug with nested allOf/anyOf:

openapi: 3.0.0
info:
  title: Minimal OpenAPI 3.0 with allOf
  version: 1.0.0
paths:
  /pets:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PetCreate'
      responses:
        '201':
          description: Created
components:
  schemas:
    Pet:
      type: object
      properties:
        id:
          type: integer
    Cow:
      type: object
    PetCreate:
      allOf:  
        - anyOf:
          - $ref: '#/components/schemas/Pet'
          - $ref: '#/components/schemas/Cow'
        - properties: 
            name:
              type: string
  @Test
    public void allOfAnyOfResolveFully() {
        ParseOptions options = new ParseOptions();
        options.setResolveFully(true);
        OpenAPI openAPI = new OpenAPIV3Parser().read("required-anyOf.yaml", null, options);

        RequestBody requestBody = openAPI.getPaths().get("/pets").getPost().getRequestBody();
        Schema requestBodySchema = requestBody.getContent().get("application/json").getSchema();
        assertNull(requestBodySchema.get$ref()); // has been inlined

        Schema schema = requestBody.getContent().get("application/json").getSchema();
        assertEquals(schema.getProperties().size(),2);  // <!--FAILS, since id got lost
    }