Swagger-ui: Examples referenced with $ref are not rendered correctly

Created on 5 Oct 2018  路  18Comments  路  Source: swagger-api/swagger-ui

Not sure if a regression of https://github.com/swagger-api/swagger-ui/issues/4021

This renders the example but also adds the $$ref key

openapi: '3.0.0'
info:
  title: 'test'
  version: '1.0.0'
paths:
  /hello:
    get:
      description: 'Get welcome message.'
      responses:
        '200':
          description: 'welcome message'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Welcome'
              example:
                $ref: '#/components/examples/WelcomeExample'
components:
  schemas:
    Welcome:
      type: object
      properties:
        message:
          type: string
  examples:
    WelcomeExample:
      value:
        api_identifier: act_12345

And this one shows the $ref key instead of parsing it (Although the editor shows an error if the $ref doesn't exist):

openapi: '3.0.0'
info:
  title: 'test'
  version: '1.0.0'
paths:
  /hello:
    get:
      description: 'Get welcome message.'
      responses:
        '200':
          description: 'welcome message'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Welcome'
              example:
                $ref: '#/components/examples/WelcomeExample'
components:
  schemas:
    Welcome:
      type: object
      properties:
        message:
          type: string
  examples:
    WelcomeExample:
      value:
        api_identifier: act_12345

All of this tested in the swagger editor.

P1 bug

Most helpful comment

I would like add another argument to the case for resolution.
Is the current behavior for schemas.
As a developer trying to define an API, I don't see why I can have nested schema references but not nested example references.

From my point of view, what is wrong in this example is the value key being rendered. Why can I reuse schemas but not examples?

openapi: '3.0.0'
info:
  title: 'test'
  version: '1.0.0'
paths:
  /hello:
    get:
      description: 'Get welcome message.'
      responses:
        '200':
          description: 'welcome message'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Welcome'
components:
  schemas:
    Welcome:
      type: object
      properties:
        message:
          $ref: '#/components/schemas/Message'
    Message:
      type: object
      properties:
        title:
          type: string
        info:
          type: string
      example:
        $ref: '#/components/examples/WelcomeExample'
  examples:
    WelcomeExample:
      $ref: '#/components/examples/MessageExample'
    MessageExample:
      value:
        foo: 2
        bar: 3

All 18 comments

Yep, I see that too in 3.19.2 and quite a few releases before that

In #4021, @webron states that

The spec does not support references for example fields, only examples. This means that any value of example will be rendered as-is

I'm wondering if this same spec interpretation extends to $ref usage inside example content. If I define a schema that envelops properties of other schema types, $ref usage is permitted. But If I then want to express an example, can I use the same $ref approach, or must the example be completely literal (without any $refs)? For example, is this valid according to swagger-ui team's spec interpretation, @webron :

```yaml
paths:
/order:
post:
requestBody:
content:
'application/json':
schema:
type: object
properties:
user:
$ref: '#/components/schemas/User'
product:
$ref: '#/components/schemas/Product'
quantity:
type: integer
example:
user:
$ref: '#/components/examples/User'
product:
$ref: '#/components/examples/Product'
quantity: 1
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
Product:
type: object
properties:
id:
type: integer
name:
type: string
examples:
User:
id: 1
name: Sasha
Product:
id: 1
name: Book

I think $ref should work in that case too. Clearly, passing a 10-KB piece of JSON example as a string is very problematic.

@sasha-borodin the spec isn't explicit about it, but I would expect what you shared to be rendered simply as:

              user:
                $ref: '#/components/examples/User'
              product:
                $ref: '#/components/examples/Product'
              quantity: 1

(that is, $ref's are not being dereferenced)

@webron, thanks for the response! I think there are two issues:

  1. The implementation both a) resolves the $ref, and b) renders an erroneous artifact of $$ref. I think that consistency needs to be achieved. Either $refs are not supported (and displayed literally), or they are supported (in which case, rendering $$ref is a bug that needs to be fixed).
  2. Since the spec isn't explicit about the matter of resolving $refs inside examples, I would like to make a case for resolution instead of literal rendering. I think this behavior is intuitively expected by a number of users as well as some on the swagger-ui team (see @shockey's comment in #4931). What's the most appropriate channel through which to make such a case or feature request?

Thank you again.

I would like add another argument to the case for resolution.
Is the current behavior for schemas.
As a developer trying to define an API, I don't see why I can have nested schema references but not nested example references.

From my point of view, what is wrong in this example is the value key being rendered. Why can I reuse schemas but not examples?

openapi: '3.0.0'
info:
  title: 'test'
  version: '1.0.0'
paths:
  /hello:
    get:
      description: 'Get welcome message.'
      responses:
        '200':
          description: 'welcome message'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Welcome'
components:
  schemas:
    Welcome:
      type: object
      properties:
        message:
          $ref: '#/components/schemas/Message'
    Message:
      type: object
      properties:
        title:
          type: string
        info:
          type: string
      example:
        $ref: '#/components/examples/WelcomeExample'
  examples:
    WelcomeExample:
      $ref: '#/components/examples/MessageExample'
    MessageExample:
      value:
        foo: 2
        bar: 3

Encountering the same issue. Is anyone working on it?

Been running into this lately as well. Any news?

I'm picking this up - as mentioned in https://github.com/swagger-api/swagger-ui/issues/4931#issuecomment-428358133, we shouldn't be resolving example values at all.

Just trying to clarify things.

So basically we cannot use examples not only in a good way, but _in fact_. Because no one in their clear mind would insert a huge block of example data right in the middle of definitions - and that is exactly what we're forced to do, because:

1) Arrays is what desperately needs loads of data,
2) but arrays can only consume example and not examples,
3) which is actually the only option to decouple definitions and data.
4) And this nonsense behavior we totally owe to some API spec, sent from above.

Did I get it right?

Couldn't really follow what you're saying, but regardless, this is how the spec is defined, not something within the control of this tool.

I agree with @alexgmin. Could we request the ability to nest examples so we can, uhm... reuse definitions? After all, that's the whole idea of Domains, isn't it?

@carlos-soto you can propose changes to the OpenAPI Specification here:
https://github.com/OAI/OpenAPI-Specification/issues

Would be nice in addition to support arrays in example:

responses:
  "200":
    content:
      application/json:
        example:
          - $ref: "#/components/examples/sample1"
          - $ref: "#/components/examples/sample2"
          - $ref: "#/components/examples/sample3"

@dmak you can propose changes to the OpenAPI Specification syntax constructs here:
https://github.com/OAI/OpenAPI-Specification/issues

As of OAS 3.0.3, multiple examples require the use of the examples keyword:

responses:
  "200":
    content:
      application/json:
        examples:
          sample1:
            $ref: "#/components/examples/sample1"
          sample2:
            $ref: "#/components/examples/sample2"
          sample3:
            $ref: "#/components/examples/sample3"

What do you think about the issue where $ref used in examples (plural, which is valid, and part of the OpenAPI specification as opposed to inside example (singular)) is dereferenced properly, but also causes an artifact of $$ref being added to the dereferenced object?

So for example this:

...
examples:
  Users:
    value:
      - $ref: '#/components/examples/User1/value'
      - $ref: '#/components/examples/User2/value'
...

Renders as this (in JSON):

[
  {
    "id": 1,
    "email": "[email protected]",
    "name": "John Doe",
    "$$ref": "#/components/examples/User1/value"
  },
  {
    "id": 2,
    "email": "[email protected]",
    "name": "Jane Doe",
    "$$ref": "#/components/examples/User2/value"
  }
]

Notice the "$$ref": "#/components/examples/User*/value" as the last property. This seems to be an issue regardless what's going on with example (singular) also mentioned in https://github.com/swagger-api/swagger-ui/issues/4924#issuecomment-428411720

Should that be opened as a separate issue than?

@BenceSzalai

What do you think about the issue where $ref used in examples (plural, which is valid, and part of the OpenAPI specification as opposed to inside example (singular)) is dereferenced properly, but also causes an artifact of $$ref being added to the dereferenced object?

...
examples:
  Users:
    value:
      - $ref: '#/components/examples/User1/value'
      - $ref: '#/components/examples/User2/value'
...

This is not valid usage. $ref is supported only under examples.<name>, that is:

examples:
  Users:
    $ref: '#/components/examples/User1'

The value keyword is an analog of example (singular) and requires an inline example value.

Should that be opened as a separate issue than?

5625

Oh, makes sense! Thanks for providing clarity!

Was this page helpful?
0 / 5 - 0 ratings