Skip to content

Add support for nested references #2144

@VYDocuWare

Description

@VYDocuWare

Describe the bug

var openApiStringReader = new OpenApiStringReader();
var result = openApiStringReader.Read(openApiDoc, out var diagnostic);

When I use the above code with openApiDoc = to the attached yaml, I get the following exception:

Microsoft.OpenApi.Exceptions.OpenApiException: 'The reference string '/components/schemas/CurrentTrack/properties/title' has invalid format.'

The yaml is valid according to the Swagger Editor (https://editor.swagger.io/)

OpenApi File To Reproduce

openapi: 3.0.0
info:
    version: 1.0.0
    title: Radio.co Public API
    contact:
        name: API Support
        url: help.radio.co
        email: [email protected]
    x-logo:
        url: "https://radio.co/assets/downloads/Logo--Full-Colour-for-Light-Backgrounds.png"
    description: Radio.co public API
servers:
    - url: "https://public.radio.co"
paths:
    "/stations/{station_id}/status":
        get:
            summary: Get station status
            description: Get the current status of a station.
            operationId: statusAction
            tags:
                - Status
            parameters:
                - $ref: "#/components/parameters/station_id"
            responses:
                "200":
                    description: Station status
                    content:
                        application/json:
                            schema:
                                title: Status
                                type: object
                                description: The station status
                                required:
                                    - status
                                    - source
                                    - collaborators
                                    - relays
                                    - current_track
                                    - history
                                    - logo_url
                                    - streaming_hostname
                                    - outputs
                                properties:
                                    status:
                                        type: string
                                        description: The station status.
                                        enum:
                                            - online
                                            - offline
                                        example: online
                                    source:
                                        title: Source
                                        type: object
                                        description: The source of station playback.
                                        required:
                                            - type
                                            - collaborator
                                            - relay
                                        properties:
                                            type:
                                                type: string
                                                description: The source type.
                                                enum:
                                                    - automated
                                                    - live
                                                example: automated
                                            collaborator:
                                                nullable: true
                                                allOf:
                                                    - $ref: "#/components/schemas/Collaborator"
                                            relay:
                                                nullable: true
                                                allOf:
                                                    - $ref: "#/components/schemas/Relay"
                                    collaborators:
                                        type: array
                                        description: Currently connected collaborators.
                                        items:
                                            $ref: "#/components/schemas/Collaborator"
                                    relays:
                                        type: array
                                        description: Currently connected relays.
                                        items:
                                            $ref: "#/components/schemas/Relay"
                                    current_track:
                                        $ref: "#/components/schemas/CurrentTrack"
                                    history:
                                        type: array
                                        description: An array of history items.
                                        items:
                                            type: object
                                            required:
                                                - title
                                            properties:
                                                title:
                                                    $ref: "#/components/schemas/CurrentTrack/properties/title"
                                    logo_url:
                                        type: string
                                        description: The station logo URL.
                                        format: uri
                                        example: "https://images.radio.co/station_logos/s7ee52dd88.20161028115811.png"
                                    streaming_hostname:
                                        type: string
                                        description: A hostname. Should be valid according to RFC1123
                                        pattern: '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$'
                                        example: stream.radio.co
                                    outputs:
                                        type: array
                                        description: Possible outputs.
                                        items:
                                            title: Output
                                            type: object
                                            required:
                                                - name
                                                - format
                                                - bitrate
                                            properties:
                                                name:
                                                    type: string
                                                    description: Output name.
                                                    pattern: "^[a-z0-9]+$"
                                                format:
                                                    type: string
                                                    description: Output format.
                                                    enum:
                                                        - MP3
                                                        - AAC
                                                bitrate:
                                                    type: number
                                                    description: Output bitrate.
                                                    enum:
                                                        - 16
                                                        - 32
                                                        - 48
                                                        - 64
                                                        - 96
                                                        - 128
                                                        - 192
                                                        - 256
                                                        - 320
    "/stations/{station_id}/history":
        get:
            parameters:
                - $ref: "#/components/parameters/station_id"

            summary: Get station history
            description: Get the track history of a station.
            operationId: getHistoryAction
            tags:
                - History
            responses:
                "200":
                    description: Station track history
                    content:
                        application/json:
                            schema:
                                title: History
                                type: object
                                description: The station track history
                                required:
                                    - tracks
                                properties:
                                    tracks:
                                        type: array
                                        description: Track history items.
                                        maxItems: 20
                                        items:
                                            title: Track
                                            type: object
                                            required:
                                                - title
                                                - start_time
                                                - artwork_url
                                            properties:
                                                title:
                                                    $ref: "#/components/schemas/CurrentTrack/properties/title"
                                                start_time:
                                                    type: string
                                                    description: Date and time of when the track started.
                                                    format: date-time
                                                artwork_url:
                                                    $ref: "#/components/schemas/Artwork/properties/url"
    "/stations/{station_id}/next":
        get:
            summary: Get upcoming track
            description: Get the upcoming track for a station.
            operationId: getNextTrackAction
            tags:
                - Next
            parameters:
                - in: path
                  name: station_id
                  description: Owning station id.
                  required: true
                  schema:
                      $ref: "#/components/parameters/station_id/schema"
            responses:
                "200":
                    description: Upcoming track
                    content:
                        application/json:
                            schema:
                                title: Next
                                type: object
                                description: The station track history
                                required:
                                    - station_name
                                    - next_track
                                properties:
                                    station_name:
                                        title: Station name
                                        type: string
                                        example: MCR Live
                                    next_track:
                                        title: Track
                                        type: object
                                        description: Upcoming track.
                                        required:
                                            - title
                                            - artwork_url
                                            - artwork_url_large
                                        properties:
                                            title:
                                                $ref: "#/components/schemas/CurrentTrack/properties/title"
                                            artwork_url:
                                                $ref: "#/components/schemas/Artwork/properties/url"
                                            artwork_url_large:
                                                $ref: "#/components/schemas/Artwork/properties/large_url"
    "/stations/{station_id}/requests":
        parameters:
            - $ref: "#/components/parameters/station_id"
        post:
            summary: Request a track
            description: Request a track
            operationId: requestTrackAction
            tags:
                - Requests
            requestBody:
                description: Requested track
                required: true
                content:
                    application/json:
                        schema:
                            title: Requested Track
                            type: object
                            required:
                                - track_id
                            properties:
                                track_id:
                                    type: integer
                                    example: 1337
                                    minimum: 0
                    application/xml:
                        schema:
                            type: object
                            properties:
                                "":
                                    type: string
                        examples:
                            example-1:
                                value:
                                    "": string
            responses:
                "201":
                    description: Track requested.
                "403":
                    description: Requests disabled.
                    content:
                        application/json:
                            schema:
                                $ref: "#/components/schemas/StandardErrorSchema"
                "404":
                    description: Requested track not found.
                    content:
                        application/json:
                            schema:
                                $ref: "#/components/schemas/StandardErrorSchema"
                "409":
                    description: You have already requested this track.
                    content:
                        application/json:
                            schema:
                                $ref: "#/components/schemas/StandardErrorSchema"
                "429":
                    description: You can not make any more requests at this time.
                    content:
                        application/json:
                            schema:
                                $ref: "#/components/schemas/StandardErrorSchema"
    "/stations/{station_id}/requests/tracks":
        get:
            summary: Get request-able tracks
            description: Get the available tracks for request for a station
            operationId: getRequestableTracks
            parameters:
                - $ref: "#/components/parameters/station_id"
            tags:
                - Requests
            responses:
                "200":
                    description: Available tracks
                    content:
                        application/json:
                            schema:
                                title: Request-able Tracks
                                type: object
                                required:
                                    - tracks
                                properties:
                                    tracks:
                                        description: Request-able track items.
                                        type: array
                                        items:
                                            title: Track
                                            type: object
                                            properties:
                                                id:
                                                    type: number
                                                    example: 1337
                                                    title: Track identity
                                                    description: The identity of the track.
                                                    minimum: 1
                                                artist:
                                                    type: string
                                                    description: Track artist
                                                    example: Darude
                                                title:
                                                    $ref: "#/components/schemas/CurrentTrack/properties/title"
                                                artwork:
                                                    $ref: "#/components/schemas/Artwork"
    "/stations/{station_id}/embed/schedule":
        get:
            parameters:
                - $ref: "#/components/parameters/station_id"
            summary: getSchedule
            tags: [Schedule]
            operationId: getStationSchedule
            description: Get a 2 week period of a stations schedule
            responses:
                "200":
                    description: OK
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    data:
                                        type: array
                                        items:
                                            $ref: "#/components/schemas/PublicSchedule"
components:
    parameters:
        station_id:
            in: path
            name: station_id
            description: Owning station id.
            required: true
            schema: {}
    schemas:
        Artwork:
            title: Artwork
            type: object
            properties:
                url:
                    type: string
                    format: uri
                    nullable: true
                large_url:
                    type: string
                    format: uri
                    nullable: true
        Collaborator:
            title: Collaborator
            type: object
            description: The currently broadcasting collaborator.
            required:
                - id
                - name
                - status
            properties:
                id:
                    type: string
                    example: ud160d49ee
                    pattern: "^u[a-f0-9]{9}$"
                    description: User identity.
                name:
                    type: string
                    description: User name.
                    example: John Doe
                status:
                    type: string
                    description: Collaborator status.
                    enum:
                        - streaming
                        - pending
                    example: pending
        CurrentTrack:
            title: Current Track
            type: object
            description: Currently playing track.
            required:
                - title
                - start_time
                - artwork_url
                - artwork_url_large
            properties:
                title:
                    type: string
                    description: Track title
                    example: 2018 Summer Jingle
                start_time:
                    type: string
                    description: Date and time of when the track started.
                    format: date-time
                artwork_url:
                    $ref: "#/components/schemas/Artwork/properties/url"
                artwork_url_large:
                    $ref: "#/components/schemas/Artwork/properties/large_url"
        Relay:
            title: Relay
            type: object
            description: The currently live relay.
            required:
                - id
                - url
                - status
            properties:
                id:
                    type: integer
                    example: 1337
                    minimum: 1
                    description: Relay identity.
                url:
                    type: string
                    description: Relay URL.
                    format: uri
                    example: "http://streaming.radio.co/s307b15171/listen"
                status:
                    type: string
                    description: Relay status
                    enum:
                        - connected
                    example: connected
        StandardErrorSchema:
            title: StandardErrorSchema
            type: object
            description: Standard error response
            required:
                - errors
            properties:
                errors:
                    type: array
                    description: collection of errors
                    items:
                        title: Error
                        type: object
                        description: Standard error
                        required:
                            - code
                            - message
                        properties:
                            code:
                                type: integer
                                minimum: 1
                                description: Error code. Will mirror a HTTP error code if we dont have anything more specific
                            message:
                                type: string
                                description: User friendly error message
                                example: Track not found
        PublicSchedule:
            title: PublicSchedule
            type: object
            description: Contains event and playlist data
            properties:
                start:
                    type: string
                    format: date-time
                end:
                    type: string
                    format: date-time
                playlist:
                    type: object
                    required:
                        - name
                        - colour
                        - artist
                        - title
                        - artwork
                    properties:
                        name:
                            type: string
                        colour:
                            type: string
                            example: "#123abc"
                            pattern: "^#[0-9a-fA-F]{6}$"
                        artist:
                            type: string
                        title:
                            type: string
                        artwork:
                            type: string
                            nullable: true
                            format: uri
            required:
                - start
                - end
                - playlist
tags:
    - name: History
      description: History
    - name: Next
      description: Next
    - name: Requests
      description: Requests
    - name: Status
      description: Requests
x-hasEquivalentPaths: true

Expected behavior
The yaml is parsed without issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    external-referencepriority:p1High priority but not blocking. Causes major but not critical loss of functionality SLA <=7daysstatus:waiting-for-internal-feedbackNeeds internal stakeholder(s) input to resolve

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions