Change default API spec URL in Swagger UI - swagger

I'm using the Swagger Editor Docker image for defining my API specification and generate a nodejs server to run as stub api and serve the documentation for my API spec.
I would like to know if it is possible to change the default URL to my own in order to present my spec when I open the page, and how I would do that.
For instance, I would like to change the default address to http://localhost:8080/spec

If I understand correctly, you used Swagger Codegen to generate a Node.js server. Now when you npm start and open Swagger UI, you want the input box (the spec URL) to display http://localhost:8080/spec instead of http://localhost/api-docs.
To change the path the .yaml spec is served from, edit your index.js as follows:
// 1 - add swaggerUi options
var uiOptions = {
apiDocs: '/spec' // <-- override the default /api-docs
};
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
...
// 2 - pass these options to swaggerUi
app.use(middleware.swaggerUi(uiOptions));
The port number is specified by the serverPort variable in index.js:
var serverPort = 8080;

Related

What is the difference between SwaggerUIBundle, and SwaggerUi

I've seen both in samples I've found and haven't seen how they are different. Is the bundle needed if you are using this in an HTML page only (not using a single-page-app) or is that the one to use if you are using a single-page-app?
The Swagger UI docs discuss two ways to deploy swagger-ui.
traditional npm - swagger-ui
dependency-free module - swagger-ui-dist
I've seen examples like this one where SwaggerUIBundle is used on what appears to be a web page hosted in tomcat (python, or some other web server) example.
<script src="./swagger-ui-bundle.js"> </script>
// later
<script>
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "https://petstore.swagger.io/v2/swagger.json",
But also seen examples like this one that use SwaggerUi.
window.swaggerUi = new SwaggerUi({
url: "http://petstore.swagger.wordnik.com/api/api-docs",
dom_id: "swagger-ui-container",
A search returns things like:
swagger-ui-bundle.js - https://github.com/swagger-api/swagger-ui/issues/3978
SwaggerUi - https://stackoverflow.com/a/29497301/3281336
SwaggerUIBundle - https://github.com/swagger-api/swagger-ui/wiki/FAQ
This page Installation Distribution Channels NPM Registry says:
SwaggerUIBundle is equivalent to SwaggerUI.
But then explains the differences. So they are functionally equivalent but the one you choose will depend on how your webserver/website is serving up the swagger user interface page.
The first example with const ui = SwaggerUIBundle(... is for Swagger UI 3.x, which is the current version of Swagger UI. The second example with window.swaggerUi = new SwaggerUi(... is for the old Swagger UI 2.x. Credit #Helen for this info in this answer)
For more details read on...
SwaggerUI Explained
SwaggerUI is used in apps that can import npm modules. This includes React, Angular or other single-page-apps (SPAs) that include the webpack-like tooling to package the resources for delivery to the browser.
The webpage says this:
import SwaggerUI from 'swagger-ui'
swagger-ui is meant for consumption by JavaScript web projects that include module bundlers, such as Webpack, Browserify, and Rollup.
Here's an example of using the npm intalled module swagger-ui.
import SwaggerUI from 'swagger-ui'
// or use require, if you prefer
const SwaggerUI = require('swagger-ui')
SwaggerUI({
dom_id: '#myDomId'
})
SwaggerUIBundle Explained
SwaggerUIBundle is used when your app does not support importing npm modules (e.g., a java webapp).
The swagger user interface can be loaded by using the swagger index.html page (included in the swagger-ui-bundle) or by your own personal html page that includes the bundle file and uses the Javascript shown below:
The following comes from the website and is edited to highlight my above statements:
The [...] dist folder [has] swagger-ui-bundle.js, which is a build of Swagger-UI that includes all the code it needs to run in one file. The folder also has an index.html asset, to make it easy to serve Swagger-UI...
An example of how to use the SwaggerUIBundle is:
var SwaggerUIBundle = require('swagger-ui-dist').SwaggerUIBundle
const ui = SwaggerUIBundle({
url: "https://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "StandaloneLayout"
})
The SwaggerUIBundle example is confusing
It is confusing because it says:
if you're in a JavaScript project that can't handle a traditional npm module, you could do something like this:
var SwaggerUIBundle = require('swagger-ui-dist').SwaggerUIBundle
which uses require() which is an npm module way of including the bundle.
A less confusing way to explain this would be to say:
If you are using Swagger in a non-module environment then you need to somehow get the swagger bundle javascript loaded into the browser page and then use the SwaggerUIBundle as shown below to make the swagger user interface render at the dom_id specified (in the example below it is swagger-ui).
const ui = SwaggerUIBundle({
url: "https://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "StandaloneLayout"
})
The way you load the swagger-ui-bundle onto your page will depend on the technologies you are using. If you want you can load the page using a <script src="bundle.js"></script>. See https://github.com/swagger-api/swagger-ui/blob/master/dist/index.html (which is in swagger-ui/dist/index.html).
If you are in a NodeJS express application you could load the swagger bundle onto the page using:
var SwaggerUIBundle = require('swagger-ui-dist').SwaggerUIBundle
How you get the swagger bundle javscript onto the page is up to you.
The first example with const ui = SwaggerUIBundle(... is for Swagger UI 3.x, which is the current version of Swagger UI.
The second example with window.swaggerUi = new SwaggerUi(... is for the old Swagger UI 2.x.
See here for the differences between 3.x and 2.x.

Maintaining oath callback URLs

I'm developing a Loopback-based NodeJS app that uses GitHub Passport auth. For my development, I use localhost in my callbackURL setting in providers.json, but I have to change it to the published URL every time I deploy. At the same time, I have to change the same setting on GitHub.
How do you handle such scenarios? Is it possible to put a setting in providers.json? Is it possible to use two applications on GitHub and switch between them?
Probably you are loading the providers.json file in your server.js like in documentation: (https://loopback.io/doc/en/lb3/Configuring-providers.json.html)
var config = {};
try {
config = require('../providers.json');
} catch (err) {
console.trace(err);
process.exit(1); // fatal
}
So you can create two separate providers.json files (e.g. providers.dev.json providers.prod.json) and load a proper one according to e.g. NODE_ENV environment variable

How to access swagger yaml defined objects from javascript

I used Swagger Yaml to describe an endpoint and generate the mock server. The existing endpoint (that I'm mocking) doesn't follow RESTful principles 100%, so I simply want to overwrite the response that is returned by the mock server. The simple server code is shown below:
var swagger = require('swagger-server');
var server = swagger('map-cache.yaml');
var port = 7072;
server.post('/map-qa_trunk/v2/getData', function(req, res, next) {
var foo = {
err : 123,
msg : "error message"
};
res.json(foo);
});
server.listen(port, function() {
console.log('Map Cache Mock Server is now running at http://localhost:' + port);
});
In the Yaml definition, there is an object defined called MapResponseData, how do I create an instance of this object so that I can populate it as needed and return in the res.json()? Something similar to below:
var response = getMapResponseData(); // don't know what this call should be
response.fieldA = 123;
res.json(response);
I am guessing this should be possible, since Swagger parsed the YAML file and is aware of all definitions that were specified.
Try outputting the request object to console.log to see if you can find reference to the swagger definition. Another option would be to pull the parsed swagger definition from the yaml file (using js-yaml for example) and extracting from there.
However, my best advice is to use swagger-tools instead of swagger-server. The swagger-server package is alpha version and has fewer downloads, revisions, and users than swagger-tools. Benefit of swagger-tools is that it will be actively maintained and there is a larger community that can support you. To convert your project to swagger-tools, use swagger.io > Swagger Editor > Online Editor > Paste yaml in left pane > Generate Server > Node.js
In swagger-tools the entire Swagger Yaml definition is contained in each request object:
req.swagger.swaggerObject
and you can pull the response object definitions from that as needed.

How to publish swagger editor left window as documentation

I want to publish the right side panel of the swagger editor.
Currently, the team has to share the yaml file and each user has to copy & paste the text into the swagger editor to view the right panel rendering.
Is there a way to publish the content to html so that a page would look like the right panel ?
Example swagger editor windown with formated look on the right:
http://azimi.me/presentations/building-swagger-editor/images/swagger-ui.png
AFAIK there is no way to publish it right from the swagger editor but you can use swagger-ui. All you need is to
download swagger-ui
host it on a web server that is accessible for your team
save your swagger documentation code to a new file of any filename and host it on your web server, too.
tell swagger-ui which documentation file it shall load.
For the last step look for the following piece of code within the swagger-ui's index.html:
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "http://petstore.swagger.io/v2/swagger.json";
}
Replace the value of line url = "http://petstore.swagger.io/v2/swagger.json"; to point to the swagger documentation file you uploaded.

best way to tell swaggerui where the host is

When I build my swagger.json file I do not know which host to use. However I can work it out when my page that hosts swaggerui loads (in fact I might want to offer the user a choice). I hoped to see an options.host on the config for the swaggerUI object - I dont see one. Is there an existing way of doing this that I cant find or do I simply have to hack my way through the code and add this capability (pointers to the best place to do it would be welcome)
Swagger has a built-in json definition for host config, or can accept multiple inputs.
{
"swagger": "2.0",
"info": {
"title": "Why API",
"description": "Don't make that mistake again",
"version": "0.0.1"
},
"host": "127.0.0.1:3000",
"schemes": [
"https"
]
}
Or
"host": "test.mydomain.com:3000",
"schemes": [
"https"
],
Or you can have a dynamic host by defining a var and calling a hostname or machine name or other environment variables.
dynamic example
if (typeof this.host === 'undefined' || this.host === '') {
this.host = location.host;
}
if (location.port) {
this.host = this.host + ':' + location.port;
}
Here is what I do, since the loaded in document is just a JSON object:
var swaggerDoc = require('./api/swagger.json');
if (process.env.NODE_ENV === 'development') {
swaggerDoc.host="localhost:" + process.env.PORT
}
// Initialize the Swagger middleware
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
// Other initialization
}
This way you don't pollute your API specification with development environment configuration.
In recent versions of Swagger UI it's possible to do this, for example in onComplete:
window.swaggerUi.api.setHost("your.host:4242");
If you are hosting it on same app server, just remove the host key from the json and provide relative path in key "basePath". as -
"basePath": "/rest/createcampaign".
two ways
One modify swagger.js so that it accepts host option. swagger-UI passes options to swagger-js so that works. I submitted a pull to swagger-js with this fix
Second choice is that swagger-UI accepts a 'spec' parameter. This means that the hosting page can load the swagger.json file, JSON.parse it , set 'host' in it and then pass to swaggerUi constructor. This is harder for the caller but doesn't require code changes to swagger
There are 2 ways which you can follow:
Load the index.html and replace the https://petstore.swagger.io/v2/swagger.json with the url where your swagger.json is hosting.
you can expose the local swagger.json on the same server.
When you follow this approach make sure you include static files in the end of above steps.
If you don't want to expose swagger.json as an API, copy the sawgger.json in the dist folder of swagger. The index.html and swagger.json must be in same repository for this. It is inside the index.html of dist folder of swagger-ui-dist.
const ui = SwaggerUIBundle({
spec: location.host,
url: "swagger.json",
dom_id: "#swagger-ui",
deepLinking: true,
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
plugins: [SwaggerUIBundle.plugins.DownloadUrl],
layout: "StandaloneLayout"
});
// End Swagger UI call region
window.ui = ui;
};
Second way, host parameter in the swagger.yaml/swagger.json either make it empty
"host":""
or omit host parameter.
Swagger take the server's host as host where the swagger ui is hosted.
This is how I did this using the Java client:
DefaultApi api = new DefaultApi();
api.getApiClient().setBasePath("http://localhost:8080");
//call the API
if you use OpenApi 3.0
Variables can have arbitrary values, or may be restricted to an enum. In any case, a default value is required, which will be used if the client does not supply a value.
swagger doc
In the swagger-ui there will be the default value but the field is an input field so it is possible to customize it at runtime.
Swagger UI express itself is giving the following snippet it's getting the current host and publish dynamic with host
app.use('/api-docs', function(req, res, next){
swaggerDocument.host = req.get('host');
req.swaggerDoc = swaggerDocument;
next();
}, swaggerUi.serve, swaggerUi.setup());

Resources