Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Examples referenced with $ref are not rendered correctly #4924

Closed
alexgmin opened this issue Oct 5, 2018 · 21 comments · Fixed by swagger-api/swagger-js#1465
Closed

Examples referenced with $ref are not rendered correctly #4924

alexgmin opened this issue Oct 5, 2018 · 21 comments · Fixed by swagger-api/swagger-js#1465

Comments

@alexgmin
Copy link

alexgmin commented Oct 5, 2018

Not sure if a regression of #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.

@alexgmin alexgmin changed the title examples referenced with $ref are not rendered correctly Examples referenced with $ref are not rendered correctly Oct 5, 2018
@lrtherond
Copy link

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

@sasha-borodin
Copy link

sasha-borodin commented Oct 7, 2018

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 :

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

@lrtherond
Copy link

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

@webron
Copy link
Contributor

webron commented Oct 10, 2018

@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)

@sasha-borodin
Copy link

sasha-borodin commented Oct 10, 2018

@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 Reusing examples Rendering issue. #4931). What's the most appropriate channel through which to make such a case or feature request?

Thank you again.

@alexgmin
Copy link
Author

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

@dkrantsberg
Copy link

Encountering the same issue. Is anyone working on it?

@qbedard
Copy link

qbedard commented Feb 21, 2019

Been running into this lately as well. Any news?

@shockey
Copy link
Contributor

shockey commented Apr 5, 2019

I'm picking this up - as mentioned in #4931 (comment), we shouldn't be resolving example values at all.

@OnkelTem
Copy link

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?

@webron
Copy link
Contributor

webron commented Mar 24, 2020

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.

@carlos-soto
Copy link

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?

@hkosova
Copy link
Contributor

hkosova commented Jun 10, 2020

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

@dmak
Copy link

dmak commented Jun 12, 2020

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"

@hkosova
Copy link
Contributor

hkosova commented Jun 12, 2020

@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"

@BenceSzalai
Copy link

BenceSzalai commented Nov 2, 2020

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 #4924 (comment)

Should that be opened as a separate issue than?

@hkosova
Copy link
Contributor

hkosova commented Nov 17, 2020

@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

@BenceSzalai
Copy link

Oh, makes sense! Thanks for providing clarity!

@random-developer-7
Copy link

I tried combining multiple $ref elements using allOf, just for the sake of it. Even though I'm getting a Structural error in Swagger editor, the output for examples seems to be correct. For e.g.,

examples:
 myTestExample:
  $ref: '#/components/examples/testExample'
  
components:
 examples:
  testExample:
   allOf:
    - $ref: '#/components/examples/data1'
    - $ref: '#/components/examples/data2'
  data1:
   value:
    'key1': 'value1'
  data2:
   value:
    'key2': 'value2'

This produces the output value for myTestExample as follows:

{
 'key1': 'value1',
 'key2': 'value2'
}

Is this an expected behaviour?

@bodo79
Copy link

bodo79 commented Mar 29, 2022

Hi @alexgmin,
I'v tried many solutions, the only one that seems to work is using 'examples' key and not 'example',
then put a single example (you should name it) and put the $ref under it.

just like this:

paths:
  /hello:
    get:
      description: 'Get welcome message.'
      responses:
        '200':
          description: 'welcome message'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Welcome'
              examples:
                WelcomeExample1: # you can give as an example name any name you want
                  $ref: '#/components/examples/WelcomeExample'

@Shannanigans
Copy link

Shannanigans commented May 5, 2022

@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

I am surprised to find that this ticket is closed. Using references in component examples in a similar manner to schema seems to be an intuitive and expected behaviour for many.

A list endpoint which is making use of an enveloped response becomes difficult to create an example for without duplication of the single instance example data which is required for other endpoints.

  examples:
    someResponse:
      value:
        count: 15
        next: null
        previous: null
        results:
          - $ref: '#/components/examples/exampleOne/value'
          - $ref: '#/components/examples/exampleTwo/value'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.