How to refer to an external JSON file containing response examples in Swagger?

6.4k views Asked by At

In my Swagger spec file, I want to return example responses, for that I can add examples in response. But that makes my spec file quite big and error prone. Is there a way to refer to a file containing JSON of an example object?

I tried something like below but it doesn't seem to work.

get:
  tags:
    - businesses
  summary: Get Taxable Entities details 
  description: ''
  operationId: getTaxableEntities
  produces:
    - application/json
  parameters:
    - name: business_id
      in: path
      required: true
      type: integer
      format: int32
    - name: gstIn
      in: query
      required: false
      type: integer
      format: int32
  responses:
    '200':
      description: Taxable Entities
      schema:
        type: file
        default:
          $ref: taxable_entity_example.json
    '401':
      description: You are not authorised to view this Taxable Entity
2

There are 2 answers

0
Helen On

The example keyword does not support $ref, and OpenAPI 2.0 does not have a way to reference external examples.

You need OpenAPI 3.0 (openapi: 3.0.0) to be able to reference external examples. OAS3 provides the externalValue keyword for this purpose:

openapi: 3.0.2
...

      responses:
        '200':
          description: Taxable Entities
          content:
            application/json:
              schema:
                type: object
              examples:
                myExample:  # arbitrary name/label
                  externalValue: 'https://myserver.com/examples/taxable_entity_example.json'

externalValue can be an absolute or relative URL. Note that relative externalValue URLs are resolved against the API server URL (servers[*].url) and not the location of the API definition file.

Note for Swagger UI and Swagger Editor users: Currently (as of December 2019) the content of externalValue examples is not displayed. Follow this issue for updates.

1
阿尔曼 On

You can do it with wrapComponents

Sample openapi.yaml

openapi: 3.0.1
info:
  title: Swagger Petstore
  description: 'This is a sample server Petstore server'
  version: 1.0.0
servers:
- url: https://petstore.swagger.io/v2
- url: http://petstore.swagger.io/v2
paths:
  /router/rest:
    get:
      summary: test
      operationId: test
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
              examples:
                success:
                  summary: JSON example
                  value: Loading...
                  externalValue: 'example/test.json'
            application/xml:
              schema:
                type: object
                xml:
                  name: xml
              examples:
                success:
                  summary: XML example
                  value: Loading...
                  externalValue: 'example/test.xml'

Add a custom plugin to index.html

// Examples map
const examples = {};

// Custom plugin for the logic that happens before the response element is created
const CustomPlugin = () => {
  return {
    wrapComponents: {
      response: (Original, { React, oas3Actions, oas3Selectors }) => (props) => {
        const contentType = oas3Selectors.responseContentType(props.path, props.method)
        const externalValue = props.response.getIn(['content', contentType, 'examples', props.activeExamplesKey, 'externalValue'])
        // Check if externalValue field exists
        if (externalValue) {
          // Check if examples map already contains externalValue key
          if (examples[externalValue]) {
            // Set example value directly from examples map
            props.response = props.response.setIn(['content', contentType, 'examples', props.activeExamplesKey, 'value'], examples[externalValue])
          } else {
            // Download external file
            fetch(externalValue)
            .then(res => res.text())
            .then(data => {
              // Put downloaded file content into the examples map
              examples[externalValue] = data
              // Simulate select another example action
              oas3Actions.setActiveExamplesMember({
                "name": 'fake',
                "pathMethod": [props.path, props.method],
                "contextType": "responses",
                "contextName": props.code
              })
              // Reselect this example
              oas3Actions.setActiveExamplesMember({
                "name": props.activeExamplesKey,
                "pathMethod": [props.path, props.method],
                "contextType": "responses",
                "contextName": props.code
              })
            })
            .catch(e => console.error(e))
          }
        }
        return React.createElement(Original, props)
      }
    }
  }
}

window.onload = function() {
  const ui = SwaggerUIBundle({
    url: 'openapi.yaml',
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIStandalonePreset
    ],
    plugins: [
      SwaggerUIBundle.plugins.DownloadUrl,
      // Add custom plugin
      CustomPlugin
    ],
    layout: "StandaloneLayout"
  });

  window.ui = ui;
};