open-api-renderer icon indicating copy to clipboard operation
open-api-renderer copied to clipboard

Nested oneOf Schema

Open zbuckley opened this issue 8 years ago • 2 comments

Love how clean this thing looks when generating a requestBody with a complicated schema, but we ran into one particular case that didn't seem supported.

There doesn't seem to be support for nesting multiple layers of oneOf.

If you render the example below you'll see that only the oneOf at the top-level (in /example's schema object), is toggled through the "Option 1", "Option 2" drop-down for the Request Body section. The Example Request, also has a oneOf on requestBody, which isn't being presented to the user.

I'm assuming this probably isn't a quick fix, but it would be a great feature to add... Would it be possible to nest the Option 1, Option 2 concept for additional anyOf layers?

I've put together an example that tries to illustrate the issue:

{
  "openapi": "3.0.0",
  "info": {
    "description": "Example Description",
    "version": "EXAMPLE",
    "title": "EXAMPLE TITLE",
  },
  "paths": {
    "/example": {
      "post": {
        "tags": [
          "Example Request"
        ],
        "summary": "/example summary",
        "description": "/example description",
        "requestBody": {
          "description": "Generic Request to be submitted",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "request",
                  "userID"
                ],
                "properties": {
                  "request": {
                    "oneOf": [
                      "$ref": "#/components/schemas/ExampleRequest",
                      "$ref": "#/components/schemas/InfoRequest"
                    ]
                  },
                  "userID": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ExampleRequest": {
        "type": "object",
        "description": "Describe Request A or B",
        "required": [
          "requestBody"
        ],
        "properties": {
          "requestBody": {
            "oneOf": [
              "$ref": "#/components/schemas/RequestA",
              "$ref": "#/components/schemas/RequestB"
            ]
          }
        }
      },
      "RequestA": {
        "type": "object",
        "description": "Description for Request A",
        "required": [
          "fieldA",
          "fieldB"
        ],
        "properties": {
          "fieldA": {
            "type": "string"
          },
          "fieldB": {
            "type": "string"
          }
        }
      },
      "RequestB": {
        "type": "object",
        "description": "Description for Request B",
        "required": [
          "fieldC",
          "fieldD"
        ],
        "properties": {
          "fieldC": {
            "type": "string"
          },
          "fieldD": {
            "type": "string"
          }
        }
      },
      "InfoRequest": {
        "type": "object",
        "description": "Description for Info Request",
        "required": [
          "fieldE",
          "fieldF"
        ],
        "properties": {
          "fieldE": {
            "type": "string"
          },
          "fieldF": {
            "type": "string"
          }
        }
      }
    }
  }
}

zbuckley avatar Oct 05 '17 22:10 zbuckley

Hey! Sorry for the delay. Can confirm that doesn't produce an ideal result. If I'm following correctly there should be 3 possible options?

  • ExampleRequest with Request A
  • ExampleRequest with Request B
  • InfoRequest

I thought that the nested scenario was handled, but I must of messed something up in the oneOfResolver. Let me try to take a look over the next week and see if I can figure it out!

@quangkhoa actually proposed your idea early in the roadmap as an alternate UI! I couldn't find out how to pull it off back then, but maybe it's something worth revisiting now as it's a nicer experience.

brendo avatar Oct 18 '17 13:10 brendo

Sorry I didn't get back to you guys sooner. Your 3 possible options are definitely what I had in mind.

zbuckley avatar Nov 08 '17 00:11 zbuckley