Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

openapi - Swagger schema properties ignored when using $ref - why?

I'm trying to build a Swagger model for a time interval, using a simple string to store the time (I know that there is also datetime):

definitions:
  Time:
    type: string
    description: Time in 24 hour format "hh:mm".
  TimeInterval:
    type: object
    properties:
      lowerBound:
        $ref: "#/definitions/Time"
        description: Lower bound on the time interval.
        default: "00:00"
      upperBound:
        $ref: "#/definitions/Time"
        description: Upper bound on the time interval.
        default: "24:00"        

For some reason the generated HTML does not show the lowerBound and upperBound "description", but only the original Time "description". This makes me think I'm not doing this correctly.

So the question is if using a model as a type can in fact be done as I'm trying to do.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

TL;DR: $ref siblings are supported in OpenAPI 3.1. In previous OpenAPI versions, any keywords alongside $ref are ignored.

OpenAPI 3.1

Your definition will work as expected when migrated to OpenAPI 3.1. This new version is fully compatible with JSON Schema 2020-12, which allows $ref siblings in schemas.

openapi: 3.1.0
...

components:
  schemas:
    Time:
      type: string
      description: Time in 24 hour format "hh:mm".

    TimeInterval:
      type: object
      properties:
        lowerBound:
          # ------- This will work in OAS 3.1 ------- #
          $ref: "#/components/schemas/Time"
          description: Lower bound on the time interval.
          default: "00:00"
        upperBound:
          # ------- This will work in OAS 3.1 ------- #
          $ref: "#/components/schemas/Time"
          description: Upper bound on the time interval.
          default: "24:00"  

Outside of schemas - for example, in responses or parameters - $refs only allow sibling summary and description keywords. Any other keywords alongside these $refs will be ignored.

# openapi: 3.1.0

# This is supported
parameters:
  - $ref: '#/components/parameters/id'
    description: Entity ID

# This is NOT supported
parameters:
  - $ref: '#/components/parameters/id'
    required: true

OpenAPI 2.0 and 3.0.x

In these versions, $ref works by replacing itself and all of its sibling elements with the definition it is pointing at. That is why

      lowerBound:
        $ref: "#/definitions/Time"
        description: Lower bound on the time interval.
        default: "00:00"

becomes

      lowerBound:
        type: string
        description: Time in 24 hour format "hh:mm".

A possible workaround is to wrap $ref into allOf - this can be used to "add" attributes to a $ref but not override existing attributes.

      lowerBound:
        allOf:
          - $ref: "#/definitions/Time"
        description: Lower bound on the time interval.
        default: "00:00"

Another way is to use replace the $ref with an inline definition.

definitions:
  TimeInterval:
    type: object
    properties:
      lowerBound:
        type: string  # <------
        description: Lower bound on the time interval, using 24 hour format "hh:mm".
        default: "00:00"
      upperBound:
        type: string  # <------
        description: Upper bound on the time interval, using 24 hour format "hh:mm".
        default: "24:00"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...