2
votes

I've created a little react app that is rendering a swagger container.The container gets its configuration from a ConfigURL - at this URL a json config file is available. The config url refers to localhost port 8080 where a local app generates and serves this json file. The task of this back-end app in the local machine to appropriate data about my various services and generate swagger configuration file - at current moment it just serves a hardcoded json file. (if you do a get request at localhost:8080 for example open it in browser you get this file). Abbreviated and censored example of the JSON.

{
"swagger": "2.0",
"info": {
"version": "v1",
"title": project title
  },
"schemes": "https",
"host": "my.services.host",
"basePath": "/",
"tags": [
  {
   "name": "service1-controller",
    "description": "Service 1 Controller"
  },
  {
   "name": "service2-controller",
    "description": "service 2 Controller"
    },
  ],

 "security": [
   {
     "Bearer": []
   }
 ],
 "paths": {
   "/ser1": {
     "get": {
       "tags": [
         "service1-controller"
        ],
        "summary": "appropriate summary",
        "operationId": "geStuffUsingGET",
        "produces": [
          "application/xml",
          "application/json"
        ],
        "parameters": [

          {
            "name": "country",
            "in": "query",
            "description": "country",
            "required": true,
            "type": "string"
          },
          {
            "name": "lang",
            "in": "query",
            "description": "lang",
            "required": false,
            "type": "string"
          },
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/Ser1Response"
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "deprecated": false
      }
    },
    "/ser2": {
      "get": {
        "tags": [
          "service2-controller"
        ],
        "summary": "appropriate summary",
        "operationId": "geStuffUsingGET",
        "produces": [
          "application/xml",
          "application/json"
        ],
        "parameters": [

          {
            "name": "country",
            "in": "query",
            "description": "country",
            "required": true,
            "type": "string"
          },
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/Ser2Response"
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "deprecated": false
      }
    },
}
  "definitions": {
    "Ser1response": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
      },
      "title": "Ser1response"
    },

    }
  },
  "securityDefinitions": {
    "Bearer": {
      "type": "apiKey",
      "name": "apikey",
      "in": "query"
    }
  }
}

In actuality it has more services with more definitions for response object. But you get the gist -- all services use a api-key in query so the user has a possibility to enter api key into swagger authorization field afterwards all request will have this key as a query parameter ?apikey=keyyouentered appended when you "try it". This part works fine and also seems to be no trigger to other propbes. Even if I remove everything related to authorization the following problems still persist.

The problem comes with other query parameters. If I choose "try it" and enter a string query variable like lang, then on "execute" push the field will be cleared and the curl command produced does not contain the query parameter. (it does contain the apikey if i keep the securitydefinition and authorize myself) If I enter a required query parameter like country the push on "execute" will clear the field - it will then turn red and focus - obviously a warning that i need to enter a required parameter. But I had in fact entered it already?

The swagger element in react

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import SwaggerUi, {presets} from 'swagger-ui';
import 'swagger-ui/dist/swagger-ui.css';

class SwaggerUI extends Component {

  componentDidMount() {
    SwaggerUi({
      defaultModelsExpandDepth: -1,
      dom_id: '#swaggerContainer',
      url: this.props.url,
      spec: this.props.spec,
      presets: [presets.apis],
    });
  }

  render() {
    return (
      <div id="swaggerContainer" />
    );
  }
}

SwaggerUI.propTypes = {
  url: PropTypes.string,
  spec: PropTypes.object
};

SwaggerUI.defaultProps = {
  url: `/v2/api-docs`
};

export default SwaggerUI

the APP main element

import React, { Component } from 'react';
import './App.css';
import SwaggerUI from './components/swagger';

class App extends Component {
  render() {
    return (
      <div>
        <SwaggerUI/>
      </div>
    )
  }
}

export default App;

to avoid getting CORS errors i have put

"proxy": "http://localhost:8080"

in my package.json -- the Json file is served on a different port and would cause CORS error.

A note : if I replace the configurl inside swagger component with a swagger default example.

SwaggerUI.defaultProps = {
  url: `http://petstore.swagger.io/v2/swagger.json`
};

The problem seems to persist - for example find pet by id (which is an integer path parameter) will act exactly like country parameter in my example - i enter the required parameter into the field click execute and get a focused to an empty red field afterwards. Interestinlgy /pet/findByStatus where there is a selection works fine - the problem seems to be with filling in fields.

The swagger container seems otherwise to be working as intended - when I leave myself unauthorized and click execute I get 401 response, when i authorize myself and click I get the empty array response with is what I should get if I do not specify lang or country query parameters. I would want to specify them though and get some other responses.

Is there something in the swagger json config file or more likely in the Swagger component that needs to be changed?

1

1 Answers

2
votes

It seems from this that React does not play nicely with SwaggerUi right about now. https://github.com/swagger-api/swagger-ui/issues/4745 Solutions would be to not use React or try to isolate the component by using iframe or ShadowDom.