Redocly / redoc

📘 OpenAPI/Swagger-generated API Reference Documentation
https://redocly.github.io/redoc/
MIT License
23.63k stars 2.3k forks source link

Documentation Failing to Render oneOf Request Schema #2571

Open hskrasek opened 3 months ago

hskrasek commented 3 months ago

Describe the bug When documenting an API I ran into a bug where the Redocly CLI build docs, or the open source HTML Element properly renders the code examples for a oneOf/discriminator requestBody but fails to present the schema, properties, and descriptions.

Expected behavior I expect the schema definition, with properties and description.

Minimal reproducible OpenAPI snippet(if possible)

openapi: 3.1.0
info:
  title: Simple Consent
  description:
    Foo bar
  version: 0.0.1
paths:
  '/ping-post/post':
    post:
      operationId: post
      summary: Transact a lead sale
      description: |
        Use the following API after a successful Ping response (see above) to transact
        a sale of a lead to Modernize Home Services, by sending full details the lead along
        with a PingToken.
      requestBody:
        $ref: '#/components/requestBodies/Post'
      responses:
        '200':
          $ref: '#/components/responses/SuccessfulPost'
components:
  schemas:
    Status:
      type: string
      enum:
        - ACCEPTED
        - REJECTED
        - ERROR
    TagId:
      type: string
      example: "204670250"
      description: |
        The tagId is unique to your publisher account and authorizes you to send leads for particular services.
        tagID=204670250 is used only for the Staging environment. Once we confirm stage tests and you move to using the production API,
        this value must be replaced with the tagID value given to you by your account manager.

        **NOTE:** Test submissions are not billable.
    ServiceType:
      type: string
      description: "The type of home service being requested, e.g., Windows Installation."
      example: "WINDOWS"
      enum:
        - ALERTS_MEDICAL
        - BATH_REMODEL
        - BATHROOM_REFACING
        - DRAINS
        - DUMPSTER_RENTAL
        - FULL_SERVICE_JUNK_REMOVAL
        - GUTTER_COVERS
        - GUTTERS
        - GUTTER_CLEANING
        - HOME_SECURITY
        - HOT_TUBS
        - HVAC
        - LABOR_SERVICES
        - MOVING
        - PLUMBING
        - ROOFING_ASPHALT
        - ROOFING_CEDAR_SHAKE
        - ROOFING_COMPOSITE
        - ROOFING_METAL
        - ROOFING_NATURAL_SLATE
        - ROOFING_TAR_TORCHDOWN
        - ROOFING_TILE
        - SEWER
        - SIDING_ALUMINIUM
        - SIDING_BRICKFACE
        - SIDING_COMPOSITE_WOOD
        - SIDING_STONEFACE
        - SIDING_VINYL
        - SOLAR
        - STAIR_LIFTS
        - TREE_SERVICES
        - WALK_IN_TUBS
        - WATER_MAIN
        - WATER_HEATERS
        - WATER_TREATMENT
        - WINDOWS
        - WALK_IN_SHOWERS
    PostalCode:
      type: string
      description: 5-digit US zip code
      example: "99751"
    NumberOfWindows:
      type: string
      example: "6-9"
      description: |
        If more than 9 windows, use `6-9`
      enum:
        - 1
        - 2
        - 3-5
        - 6-9
    BuyTimeFrame:
      type: string
      example: "Immediately"
      enum:
        - Immediately
        - 1-6 months
        - Don't Know
    OwnHome:
      type: boolean
      example: true
      description: |
        If not the owner, but is authorized to make improvements, use `Yes`
      enum:
        - true
        - false
    HomePhoneConsent:
      type: boolean
      example: false
      description: |
        **PING ONLY.** Indicates whether you gathered consent prior to pinging Modernize Home Services.
        Leave blank or use false if you did not acquire consent.
      enum:
        - true
        - false
    PartnerSourceId:
      type: string
      description: |
        Value to identify campaigns by marketing efforts or channels on the publisher side.
        Helps Modernize track and report quality back to publisher
      example: "CampaignA"
    PublisherSubId:
      type: string
      description: |
        Publisher's own transaction-level identifier for the lead.
      example: "12345"
    ConsentKeys:
      type: array
      items:
        type: string
      example:
        - "67c3eb4a9e844c6439037345"
        - "e6678asdf76589eff90b7c54"
        - "eaf593eb4a9e8c64390332ef"
        - "83528asdf76589eff90ba6309"
        - "64448asdf33869eff90baaa54"
      description: "An array of unique consent key identifiers for reference."
    HomePhoneConsentLanguage:
      type: string
      description: |
        **POST ONLY.** Complete, URL-encoded string of of consent language displayed to consumer. Send on Posts only.
      example: "<consent language goes here>"
    FirstName:
      type: string
      example: "Grizzly"
      description: First name
    LastName:
      type: string
      example: "Bear"
      description: Last name
    StreetAddress:
      type: string
      example: "9305 Nimbus Ave"
      description: Address
    City:
      type: string
      example: "Kobuk"
      description: City
    State:
      type: string
      example: "AK"
      description: State (USPS abbreviation)
    HomePhone:
      type: string
      example: "5039065030"
      description: Phone (10-digit US, no special chars)
    Email:
      type: string
      example: "example@example.com"
      description: Email
    TrustedFormToken:
      type: string
      example: "https://cert.trustedform.com/5d9f37382eca1518c752db469cacb6668049c8d3"
      description: |
        TrustedForm token or token URL **\***

        **\*** A compliance certification token is required on all leads.
        You must pass either or both of LeadIDToken (Jornaya)
        or TrustedFormToken (ActiveProspect) for a lead to be accepted.
    LeadIDToken:
      type: string
      example: "EAF0AAF2-55CD-08A7-DE78-C5A090B3A57B"
      description: |
        32-char Jornaya LeadiD Token **\***

        **\*** A compliance certification token is required on all leads.
        You must pass either or both of LeadIDToken (Jornaya)
        or TrustedFormToken (ActiveProspect) for a lead to be accepted.
    BasePostDetails:
      type: object
      properties:
        tagId:
          $ref: '#/components/schemas/TagId'
        serviceType:
          $ref: '#/components/schemas/ServiceType'
        postalCode:
          $ref: '#/components/schemas/PostalCode'
        buyTimeframe:
          $ref: '#/components/schemas/BuyTimeFrame'
        ownHome:
          $ref: '#/components/schemas/OwnHome'
        publisherSubId:
          $ref: '#/components/schemas/PublisherSubId'
        partnerSourceId:
          $ref: '#/components/schemas/PartnerSourceId'
        homePhoneConsentLanguage:
          $ref: '#/components/schemas/HomePhoneConsentLanguage'
        firstName:
          $ref: '#/components/schemas/FirstName'
        lastName:
          $ref: '#/components/schemas/LastName'
        address:
          $ref: '#/components/schemas/StreetAddress'
        city:
          $ref: '#/components/schemas/City'
        state:
          $ref: '#/components/schemas/State'
        homePhone:
          $ref: '#/components/schemas/HomePhone'
        email:
          $ref: '#/components/schemas/Email'
        consentKeys:
          $ref: '#/components/schemas/ConsentKeys'
        trustedFormToken:
          $ref: '#/components/schemas/TrustedFormToken'
        leadIDToken:
          $ref: '#/components/schemas/LeadIDToken'
      required:
        - tagId
        - buyTimeframe
        - ownHome
        - serviceType
        - postalCode
        - homePhoneConsentLanguage
        - partnerSourceId
        - publisherSubId
        - firstName
        - lastName
        - address
        - city
        - state
        - homePhone
        - email
        - consentKeys
      oneOf:
        - required:
            - leadIDToken
        - required:
            - trustedFormTokeng
    AlertsMedicalPost:
      allOf:
        - $ref: '#/components/schemas/BasePostDetails'
        - type: object
          properties:
            medicalAlertProtection:
              type: string
              enum:
                - Home
                - OnTheGo
                - Both
            whoseMedicalAlert:
              type: string
              enum:
                - Myself
                - SomebodyElse
    BathRemodelPost:
      allOf:
        - $ref: '#/components/schemas/BasePostDetails'
        - type: object
          properties:
            optIn1:
              type: boolean
              enum:
                - true
                - false
    BathroomRefacingPost:
      allOf:
        - $ref: '#/components/schemas/BasePostDetails'
    DrainsPost:
      allOf:
        - $ref: '#/components/schemas/BasePostDetails'
        - type: object
          properties:
            drainageIssue:
              type: string
              enum:
                - Pumps
                - Garbage disposal
                - Lead
  responses:
    SuccessfulPost:
      description: 'Accepted Post Response'
      content:
        'application/json':
          schema:
            type: object
            properties:
              STATUS:
                $ref: '#/components/schemas/Status'
              GDCKEY:
                type: string
  requestBodies:
    Post:
      description: 'Post Lead with Consent'
      content:
        'application/json':
          schema:
            discriminator:
              propertyName: serviceType
              mapping:
                ALERTS_MEDICAL: '#/components/schemas/AlertsMedicalPost'
                BATH_REMODEL: '#/components/schemas/BathRemodelPost'
                BATHROOM_REFACING: '#/components/schemas/BathroomRefacingPost'
                DRAINS: '#/components/schemas/DrainsPost'
            oneOf:
              - $ref: '#/components/schemas/AlertsMedicalPost'
              - $ref: '#/components/schemas/BathRemodelPost'
              - $ref: '#/components/schemas/BathroomRefacingPost'
              - $ref: '#/components/schemas/DrainsPost'

Screenshots

image image

Additional context N/A