Swagger UI: how to hide Nest.js controller method argument input field? - swagger

I'm adding Swagger UI 4 to existing Nest.js 7 project.
There was #Headers decorator for the Nest.js controller method argument.
I added #ApiBearerAuth nest.js decorator for method.
#ApiBearerAuth('MyAuth')
#Get()
async getEmployees(
#Headers('Authorization')
auth: string,
#Query() query: EmployeesQuery,
) {
The result is that I have Authorization header input field and lock icon button in Swagger UI at the same time. Lock icon button authorization works. Authorization header input field doesn't work and Swagger UI requires to fill it (input value is actually ignored by Nest.js).
How can I make Swagger authorization field to become not required and hidden?

Found how to make not required:
#ApiBearerAuth('MyAuth')
#ApiParam({
name: 'Authorization',
required: false,
description:
'(Leave empty. Use lock icon on the top-right to authorize)',
})
#Get()
async getEmployees(
#Headers('Authorization') auth: string,
#Query() query: EmployeesQuery,
) {

An alternative could be to use #Req() instead of #Headers().
#Get()
async getEmployees(
#Req() req: Request,
#Query() query: EmployeesQuery,
): Promise<Employees[]> {
const token = req.headers.authorization;
.
.
.
Note: import the type Request from express.
import { Request } from 'express';

You can also create a custom decorator.
It's better than the first answer because you don't have to pass the entire request for testing and actually hide the header in opposite to the second answer.
const AuthorizationToken = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.headers.authorization;
},
);

Related

Optional Url params in nestjs swagger

This is my code:
#Get('/get-presigned-url/:extension?')
async getS3PresignedUrl(#Param('extension') extension?: string): Promise<AwsTempPostUrlDto> {
return await this.aws.getTemporaryPostUrl(extension);
}
But the extension in the swagger is required.
How can I set url params as optional
I think you should use #Query instead of #Param

Azure Functions and Swagger UI - How to display query string paramters in swagger UI?

I'm having the following Azure Function which is HTTP triggered. I have set up Swagger for my endpoints using this link here. The following API expects a set of query string parameters, namely, "name", "email", "phone", so it can do some search against the target object. At the moment the body of the function of course is not implemented and that won't matter for this question though.
My question: How can I have the query string parameters displayed in the swagger UI?
The Function:
[FunctionName(nameof(GetBookingCalendarsFunction))]
public async Task<IActionResult> GetAllAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "bookings")] HttpRequest request,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult($"Name: {request.Query["name"]}, email: {request.Query["email"]}, phone: {request.Query["phone"]}");
}
The swagger UI for this function
Note: I don't want to use route values instead of query string parameters, because, having those parameters are optional and the callers may not want to for example provide one of them.
For example, I've tried the following but it will fail with 404 if you remove any of the parameters as it takes them as part of the route (even though it will show them up in the Swagger)
[FunctionName(nameof(GetBookingCalendarsFunction))]
public async Task<IActionResult> GetAllAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "bookings/name={name}&email={email}&phone={phone}")] HttpRequest request,
string name, string email, string phone,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult($"Name: {request.Query["name"]}, email: {request.Query["email"]}, phone: {request.Query["phone"]}");
}
I've been Googling around for hours now but couldn't find anything helpful so far. Appreciate your help.
Since you use package AzureExtensions.Swashbuckle to integrate Swagger in Azure function, we can use Attribute QueryStringParameter to configure query string according to your need. For more details, please refer to here
For example
[FunctionName("GetBookingCalendarsFunction")]
[QueryStringParameter("name", "this is name", DataType = typeof(string), Required = false)]
[QueryStringParameter("email", "this is email", DataType = typeof(string), Required = false)]
[QueryStringParameter("phone", "this is phone", DataType = typeof(string), Required = false)]
public static async Task<IActionResult> GetAllAsync(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "bookings")] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult($"Name: {req.Query["name"]}, email: {req.Query["email"]}, phone: {req.Query["phone"]}");
}

Simple.Odata: how to call a function passing parameters in asp.net mvc request body

The title is a bit misleading, here is my situation: with postman, i can call the following url issuing a post and my function works:
http://localhost/odataservice/odata/Evaluations(9)/CreateEmptyForm
For it to work, i have to send the following in the body portion:
{
"#odata.type": "#Common.Data.Client",
"ClientId": 1
}
My issue arises when i try to replicate this inside my asp.net mvc application. There, im doing
public int CreateRvaForm(int clientId, int evalId, int type)
{
var key = Task.Run(async () =>
{
var data = await
client
.For<Evaluation>(Constants.DataService.PLURAL_EVALUATIONS)
.Key(evalId)
.Function( type==0 ? Constants.DataService.FUNCTION_CREATE_RVA_EMPTY : Constants.DataService.FUNCTION_CREATE_RVA_DUPLICATE)
.Set( new{ClientId=clientId} )
.ExecuteAsScalarAsync<int>();
return data;
}).GetAwaiter().GetResult();
return key;
}
Here, the variable client is the Simple.Odata.Client object.
The error i'm getting is something related to route not found; debug shows me that the library is trying to execute the url
http://localhost/odataservice/odata/Evaluations(9)/CreateEmptyForm(clientId=XX).
I dont have access to modify the odata service.
According to this text ("Executing functions and actions"), you should rather try using Action instead of Function since action is POST-based call while function translates to HTTP GET

Select2 use a dynamic Ajax URL on call

I use the Select2 plugin (v 3.5.2) with Ajax to dynamically load elements in the list.
I have an issue as between the initialization of the Select2 (where a url property is set in the ajax helper) and the time the ajax call is made, this url might need to be changed.
So I have something like this :
$box.select2({
containerCssClass: "form-control"
minimumInputLength: 0,
allowClear: true,
ajax: {
url: someUrl,
dataType: 'json',
quietMillis: 100,
...
}
I can't figure out how, when, where to change the ajax.url value before it launches.
The help of Select2 says:
Select2 uses jQuery's $.ajax function to execute the remote call by default. An alternative transport function can be specified in the ajax settings, or an entirely custom implementation can be built by providing a custom query function instead of using the ajax helper.
But I can't find any example on how to do it.
Thanks in advance for any help. Much appreciated.
I can't figure out how, when, where to change the ajax.url value before it launches.
The ajax.url option can be specified as a static string or a method returning one in both Select2 3.5.x and 4.0.0.
$("select").select2({
ajax: {
url: function () {
return UrlHelper.RemoteAPI();
}
}
});
This is useful for changing the base URL, for example when the URL is determined at runtime or is automatically generated in a different method. If you need to change the query parameters, such as the one used for sending the search term, you need to override the ajax.data option.
$("select").select2({
ajax: {
data: function (args) {
// args is the search term in 3.5.x
// args is an object containing the query parameters in 4.0.0
// args.term is the search term in 4.0.0
return {
search: args.term || args;
};
}
}
});
The data here will be appended as query parameters by default, and will be sent as the request body if the method type is changed from GET (the default) to anything else.
Select2 uses jQuery's $.ajax function to execute the remote call by default. An alternative transport function can be specified in the ajax settings, or an entirely custom implementation can be built by providing a custom query function instead of using the ajax helper.
But I can't find any example on how to do it.
Select2 does allow for a different AJAX transport to be used by changing the ajax.transport option.
In 3.5.2, this must be a $.ajax-compatible method, so it must be able to take an object containing the success and failure callbacks.
$("select").select2({
ajax: {
transport: function (args) {
// args.success is a callback
// args.failure is a callback
// should return an object which has an `abort` method.
return $.ajax(args);
}
}
});
In 4.0.0, this must be a method which takes a params object (the same one passed to ajax.data), a success callback, and a failure callback.
$("select").select2({
ajax: {
transport: function (params, success, failure) {
var $request = $.ajax(params);
$request.then(success);
$request.fail(failure);
return $request;
}
}
});
Very Simple Javascript code to handle the same, can be used in Suitescript(Netsuite) also.
// prepare your dynamic URL inside this method and return
function getURL() {
return url + params;
}
// While binding the select2 with the dropdown set url to call a anonymous function which internally calls another function.
jQuery("select.itemDropDown").select2({
placeholder: "Select an item",
width: "200px",
minimumInputLength: 3,
ajax: {
url: function() {
return getURL()
},
dataType: 'json'
}
});

ASP.NET MVC 3 client-side validation with parameters

Following on from this post Perform client side validation for custom attribute
I am trying to get my head around how to do this, passing additional parameters to the client-side script
As I understand it so far to implement custom validation with MVC 3 the following is required
Create a custom validation attribute
Based on ValidationAttribute and implementing IClientValidatable. I have also see some examples deriving from ModelValidator, which seems to implement the functionality of both ValidationAttribute and IClientValidatable. So this is my first point of confusion as to what the diffirences are or whether ModelValidator was used in MVC 2 but is now deprecated or what ?
An instance of ModelClientValidationRule must be returned from GetClientValidationRules() to specify details such as the error message, ValidationType (which I understand to be the name of the Javascript function that will perform the client-side validation) and any additional custom parameters that the attribute may have, and that need to be passed to the Javascript validation.
I assume that the runtime (not sure which part of it) then use the ModelClientValidationRule to generate html attribute in the tag elements as follows:
data-val="true" (to indicate that the element requires validation)
data-val-[ValidationType]=[ErrorMessage]
data-val-[ValidationType].[ValidationParameters(n).Key]=[ValidationParameters(n).Value]
Implement the client-side validation logic
A Javascript function must be created and added to jQuery.validators with jQuery.validators.addmethod() so that JQuery is aware of it when it need to be executed. Something like:
jQuery.validator.addMethod(
'greaterThan',
function (value, element, params) {
/.../
return /* true or false */ ;
},
''
);
My question here is whether the signature 'function (value, element, params)' is standard for methods that will handle validation and I assume it will be called by some jQuery functionality at the appropriate time such as before a form is submitted or when an element looses fuces or on keyUp events. I just don't undertand how you can controll this i.e. choose which event is appropriete for yout custom validation.
Implement an unobtrusive adapter
This translates unobtrusive attributes to; something I am not very clear on, but assume it to be a jQuery Rule, but I am not clear on how those work. Something like
jQuery.validator.unobtrusive.adapters.add(
'futuredate',
{ },
function (options) {
options.rules['greaterThan'] = true;
options.messages['greaterThan'] = options.message;
}
);
My question here is about 'function (options)'. Is this the function that will be called before 'function (value, element, params)' and is responsible for extracting the unobtrusive tags into a data structure that can be understood by jQuery.Validation. From the code example it seems to me that options is an object that contains both, the attribute values from the tag (such as options.message) and the jQuery relevant properties it must map to (such as options.messages['ClientSideValidationFunctionName']. If so how are custom parameters retrieved and mapped.
I hope I have not added any additional confusion.
You could use the ValidationParameters property to add custom parameters to the rule:
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage,
ValidationType = "futuredate",
};
rule.ValidationParameters.Add("param1", "value1");
rule.ValidationParameters.Add("param2", "value2");
yield return rule;
}
which could be used in the adapter:
jQuery.validator.unobtrusive.adapters.add(
'futuredate',
[ 'param1', 'param2' ],
function (options) {
var param1 = options.params.param1; // shall equal 'value1'
var param2 = options.params.param2; // shall equal 'value2'
// TODO: use those custom parameters to define the client rules
}
);
UPDATE:
As requested in the comments section here's how you could pass those parameters to the custom validator rule function:
jQuery.validator.unobtrusive.adapters.add(
'futuredate',
[ 'param1', 'param2' ],
function (options) {
// simply pass the options.params here
options.rules['greaterThan'] = options.params;
options.messages['greaterThan'] = options.message;
}
);
jQuery.validator.addMethod('greaterThan', function (value, element, params) {
// params here will equal { param1: 'value1', param2: 'value2' }
return ...
}, '');

Resources