NestJS Alphabetize Endpoints in SwaggerUI - swagger

This SO answer shows that SwaggerUi will sort endpoints alphabetically if it is passed apisSorter : "alpha" when instantiated. In NestJS the config options are passed in the SwaggerModule.createDocument. I cannot see where in the config eg here I can pass this.

You can pass it as the fourth parameter to the SwaggerModule.setup method like so:
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('docs', app, document, {
swaggerOptions: {
tagsSorter: 'alpha',
operationsSorter: 'alpha',
},
});
swaggerOptions is untyped which is why you just have to know what you're passing. Found the answer in the discord server so hopefully that link doesn't expire.

To anyone trying #midopa's solution for FastifySwagger, pass the tagsSorter and operationsSorter values to uiConfig instead of swaggerOptions.
const doc = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, doc, {
uiConfig: {
tagsSorter: 'alpha',
operationsSorter: 'alpha',
},
});

Related

How to populate Adal8Service 's configOptions using config settings in Angular 7 and load when the application loads

I am using import { Adal8Service, Adal8HTTPService } from 'adal-angular8'; for Azure authentication. I am using the below in app.module.ts:
export function appInit(appConfigService: AppInitService) {
return (): any => {
appConfigService.getApplicationConfig().subscribe((res) =>{
sessionStorage.setItem("appConfig",JSON.stringify(res));
timeout(500);
});
}
}
my getApplicationConfig() is below:
public getApplicationConfig() {
return this.http.get('assets/config.json');}
and in the providers [] the below:
AuthenticationService,
AppInitService,
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [AppInitService],
multi: true
},
Adal8Service,
{ provide: Adal8HTTPService,
useFactory: Adal8HTTPService.factory,
deps: [HttpClient, Adal8Service],
multi: true
},
The here is the appInit function does not block (even removing the timeout()) the application loading and proceeds to to the
this.adalService.init(this.adalConfig);
this.adalService.handleWindowCallback();
(where this.adalConfig = sessionStorage.getItem("appConfig")).
If I refresh the page, then I am getting redirected to the Azure Ad login page properly or if I am hardcoding the configOptions of the this.adalService.init("HARDOCDE all values") then it works fine. How do I make the application block the configuration. I am storing the config values under /assets/config.json. I am not sure what I am doing wrong here. I did try reading the "json" file, but again I have to change it before proceeding to production. How do I make the application wait, there are also other config values for the application stored in the /assets/config.json file. Is the way I use the APP_INITIALIZER correct? Please point me to right direction.
The problem is not related to ADAL but related to how asynchronous functions works in javascript.
In order to block the execution of the function, you can either write down a function which waits till the response is returned by the http request or you can use library like waitfor-ES6 which can help you do that.
Change needs to be done at
export function appInit(appConfigService: AppInitService) {
return (): any => {
response = yield wait.for(appConfigService.getApplicationConfig);
sessionStorage.setItem("appConfig",JSON.stringify(response));
}
}
Please note this is not exact change but the direction of the change that you will need to perform. Hope this helps.

How can I pass filter parameter in OData read method [duplicate]

This question already has answers here:
Why my filter is not working in v2.ODataModel "read"?
(3 answers)
Closed 18 days ago.
I need to pass a parameter in my OData.
The URL has to be like this:
http://my_gateway_system:port/sap/opu/odata/sap/ZGW_TRANSF_APPROVAL_SRV_02/ztest_nameset('RUBENS')
Below is my code:
var sServiceUrl = "http://<my_gateway_system>:<port>/sap/opu/odata/sap/ZGW_TRANSF";
var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true, "username", "password");
var oJsonModel = new sap.ui.model.json.JSONModel();
oModel.read("/ztest_nameset('RUBENS')", null, null, true, function(oData, response) {
oJsonModel.setData(oData);
});
sap.ui.getCore().setModel(oJsonModel);
When I past the URL
http:// my_gateway_system:port/sap/opu/odata/sap/ZGW_TRANSF_APPROVAL_SRV_02/ztest_nameset('RUBENS')
in my browser, it works. But when I run my code, it's not working.
You are using the legacy method call of ODataModel#read (with the parameters spread out). The current signature for this method is read(sPath, mParameters). Please check out the documentation of the method: https://openui5.hana.ondemand.com/#docs/api/symbols/sap.ui.model.odata.ODataModel.html#read
In your concrete case, you should do something like:
oModel.read("/ztest_nameset('RUBENS')", {
filters: [/* your filters here */],
success: function(oData) {
oJsonModel.setData(oData);
}
});
Nevertheless, it is not clear what filter parameter you want to pass. In your example, you have no filter. The /ztest_nameset('RUBENS') URI is just a plain entity set + key. It is also not clear what errors you get. I could guess that it can be a CORS issue. You seem to be making the OData calls to some other host than the one you are serving the UI5 app from.

Can't read from file issue in Swagger UI

I have incorporated swagger-ui in my application.
When I try and see the swagger-ui I get the documentation of the API nicely but after some time it shows some error icon at the button.
The Error message is like below:
[{"level":"error","message":"Can't read from file
http://MYIP/swagger/docs/v1"}]
I am not sure what is causing it. If I refresh it works and shows error after few seconds.
I am guessing "http://MYIP/swagger/docs/v1" is not publicly accessible.
By default swagger ui uses an online validator: online.swagger.io. If it cannot access your swagger url then you will see that error message.
Possible solutions:
Disable validation:
config.EnableSwagger().EnableSwaggerUi(c => c.DisableValidator());
Make your site publicly accessible
Host the validator locally:
You can get the validator from: https://github.com/swagger-api/validator-badge#running-locally
You will also need to tell swaggerui the location of the validator
config.EnableSwagger().EnableSwaggerUi(c => c.SetValidatorUrl(<validator_url>));
To supplement the accepted answer...I just uncommented one line in the SwaggerConfig.cs. I only wanted to get rid of the red error on the main swagger page by disabling the validator.
// By default, swagger-ui will validate specs against swagger.io's online validator and display the result
// in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the
// feature entirely.
//c.SetValidatorUrl("http://localhost/validator");
c.DisableValidator();
If you are using files from swagger-ui github repo, then you can disable schema validation from your index.html file by setting validatorUrl to null in it:
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "/docs/open_api.json",
dom_id: '#swagger-ui',
validatorUrl : null, # <----- Add this line
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
If you using PHP Laravel framework with L5-Swagger just uncomment
'validatorUrl' => null,
from the config file /config/l5-swagger.php
Setting this.model.validatorUrl = null; in dist/swagger-ui.js worked for me ..
// Default validator
if(window.location.protocol === 'https:') {
//this.model.validatorUrl = 'https://online.swagger.io/validator';
this.model.validatorUrl = null;
} else {
//this.model.validatorUrl = 'http://online.swagger.io/validator';
this.model.validatorUrl = null;
}
To anynoe having similar issue when using Swashbuckle.OData:
I was having issues to integrated Swagger with our OData endpoints (using ODataController for API and Swashbuckle.OData NuGet package). I had to write our own document filter for it and add it:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "OurSolution.API");
c.DocumentFilter<SwaggerDocumentFilter>();
//c.CustomProvider((defaultProvider) => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration));
c.IncludeXmlComments(GetXmlCommentsPath());
c.UseFullTypeNameInSchemaIds();
c.RootUrl(req => ConfigurationManager.AppSettings["AppUrl"]);
})
.EnableSwaggerUi(c =>
{
c.DisableValidator();
});
Apparently in order to avoid validation error I had to comment out line which is setting ODataSwaggerProvider along with turning off validator as mentioned in posts above. This makes usefulness of Swashbuckle.OData questionable yet I didn't test whatever it works with vanilla Swashbuckle.
Note: I used approach described on GitHub page for Swashbuckle.OData but it was not working: showing no possible endpoints at all. Maybe somebody knows better solution.

Meteor Twitter Help (Meteor NOOB)

I just started learning MeteorJS and after completing the tutorial, I decided to play around with the Twitter API. Initially, I followed this tutorial
http://artsdigital.co/exploring-twitter-api-meteor-js/
Once completing that, what I wanted to do is scrape data from a tweet and display it on the client side.
N/A = proper authentication
Here's the code I've written:
if (Meteor.isClient) {
Session.setDefault('screen_name', 'John');
Template.hello.helpers({
screen_name: function () {
return Session.get('screen_name');
}
});
Template.hello.events({
'click button': function () {
T.get('search/tweets',
{
q: '#UCLA',
count: 1
},
function(err,data,response) {
var user_name = data.statuses[0].users.screen_name;
Session.set('screen_name', user_name);
}
)
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
var Twit = Meteor.npmRequire('twit');
var T = new Twit({
consumer_key: 'N/A', // API key
consumer_secret: 'N/A', // API secret
access_token: 'N/A',
access_token_secret: 'N/A'
});
});
}
What I believe the problem is that, the 'click button' function, the 'T' is seen to be undefined so the compiler doesn't know what that is or where it came. That thought did spark a thought in my mind to move what I have written inside the
if (Meteor.isServer) to if (Meteor.isClient)
But to no avail. It didn't work. What my reasoning is that once Meteor starts, the server starts, so if the server declares the variable T, shouldn't we be able to access it on the client side too?
I'm not sure if my approach is correct/don't know the conventions of Meteor/Meteor NOOB..so if someone could please help me, that will be highly appreciated!
Thanks!
You put a "var" declaration in front of your "T" variable. This binds the scope to the server side context of the app. I bet if you got rid of the var and made "T" global, then you would be able to access it from the client side as well.

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