How to avoid general Swagger Warnings? - spring

i am going to validate my swagger (v2) documentation in http://editor.swagger.io/#/ but i got follow warning message.
{
"generalSwaggerWarnings": [
{
"swaggerObject": "#/definitions/Future«object»",
"message": "Definition is defined but is not used: #/definitions/Future«object»"
}
]
}

Your scenario is a slight bit different than the example links I posted in my comment since you are not using the nested ResponseEntity. So your implementation would be something more like this:
import static springfox.documentation.schema.AlternateTypeRules.newRule;
...
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.alternateTypeRules(
newRule(typeResolver.resolve(Future.class),
typeResolver.resolve(WildcardType.class)))
;
}

Related

Remove Controller Name in Swagger UI

Is there any way to hide the controller name in the swagger-ui.
My class is like this. I do not want my controller name on the ui.
#Api(tags = {"group"})
public class MyControllerName {}
I did check some existing answers. for ex: How to remove controller list from Swagger UI did not help at all.
Create Docket bean and assign to it custom ApiInfo object, in this way:
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.ant("/foos/*"))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfo(
"My REST API",
"Some custom description of API.",
"API TOS",
"Terms of service",
new Contact("John Doe", "www.example.com", "myeaddress#company.com"),
"License of API", "API license URL", Collections.emptyList());
}
You can exclude any controller:
import { Controller, Get } from '#nestjs/common';
import { ApiExcludeController } from '#nestjs/swagger';
import { AppService } from './app.service';
#ApiExcludeController()
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#Get()
getHello(): string {
return this.appService.getHello();
}
}
This sould be good feature request to springfox team. If you need to customize the swagger-UI you should be doing it on your own.
Maybe the below steps are useful for someone.
Go to https://github.com/swagger-api/swagger-ui
Download the latest code
customize whatever you want to customize
package either as a web jar or as resources in your application
create resource handler mapping if required
Refer - https://github.com/springfox/springfox/issues/1108

How to hide #Deprecated marked APIs/Controllers when generating Swagger via Docket?

I am looking for a way to hide the APIs marked as #Deprecated so they are not visible on the swagger UI.
One way is to use the hidden = true in the #Operation annotation but thats too manual and not easy to toggle back if I decide that I want to view the Deprecated endpoints again.
Is there another way that we can achieve this via Docket config?
#Operation(
tags = "Deprecated",
deprecated = true
)
#GetMapping("/api/customer/order")
public String viewOrders() {
//
}
#Bean
public Docket orderApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("order")
.apiInfo(metadata())
.select()
.paths(PathSelectors.ant("/order/**"))
.build();
}

OpenApi: Unable to override content type using OperationBuilderPlugin

I'm wasting a lot of time trying to figure out how to set a default MediaType for my Spring Controllers in the output of the api-docs generated by SpringFox (Docket openapi v3.0). Lastly I've found an almost undocumented interface OperationBuilderPlugin that theorically allows me to set some properties in the OperationContext but unfortunately though the property I'm looking for seems to be ignored when the operation is built:
#Override
public void apply(OperationContext context) {
context.operationBuilder()
.produces(new LinkedHashSet<>(
Collections.singletonList(MediaType.APPLICATION_JSON_VALUE)));
}
Also tried to set the produces directly into Docket but still no luck
#Bean
public Docket api() {
....
return new Docket(DocumentationType.OAS_30)
.securityContexts(Collections.singletonList(securityContext()))
.securitySchemes(Collections.singletonList(authenticationScheme))
.useDefaultResponseMessages(true)
.consumes(new HashSet<>(Arrays.asList(MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE)))
.produces(new LinkedHashSet<>(Arrays.asList("application/json", "application/xml")))
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
...
}
I don't want to specify the return MediaType at controller class level (or method level) so my last chance if I can't find a cleaner solution is to manually replace the */* with the mediatype i want after I download the api-docs.json from the remote url.
Does anybody ever had the same issue?
Any help would be much appreciated, thanks in advance
Managed to resolve by myself. In the end I've overridden the bean ResponseMessagesReader with another bean MyResponseMessagesReader that do almost the same of the original class, but in the method below I've changed the condition of produces that in the case of an empty set it adds the json media type
private void applyMyReturnTypeOverride(OperationContext context) {
...
if (produces.isEmpty()) {
produces.add(MediaType.APPLICATION_JSON);
}
...
}
This is the only joint point I was able to slip into the processo of operation creation, maybe there's a better way (implementing OperationBuilderPlugin with some neatest strategy) but my time was ticking out for this solution.
Hope this helps other people that needs the same API generation behaviour

Springdoc GroupedOpenApi not following global parameters set with OperationCustomizer

When using GroupedOpenApi to define an API group, the common set of parameters that are added to every endpoint is not present in the parameters list.
Below are the respective codes
#Bean
public GroupedOpenApi v1Apis() {
return GroupedOpenApi.builder().group("v1 APIs")
// hide all v2 APIs
.pathsToExclude("/api/v2/**", "/v2/**")
// show all v1 APIs
.pathsToMatch("/api/v1/**", "/v1/**")
.build();
}
And the class to add the Standard Headers to all the endpoints
#Component
public class GlobalHeaderAdder implements OperationCustomizer {
#Override
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
operation.addParametersItem(new Parameter().$ref("#/components/parameters/ClientID"));
operation.addSecurityItem(new SecurityRequirement().addList("Authorization"));
List<Parameter> parameterList = operation.getParameters();
if (parameterList!=null && !parameterList.isEmpty()) {
Collections.rotate(parameterList, 1);
}
return operation;
}
}
Actual Output
Expected Output
Workaround
Adding the paths to be included/excluded in the application properties file solves the error. But something at the code level will be much appreciated.
Attach the required OperationCustomizerobject while building the Api Group.
#Bean
public GroupedOpenApi v1Apis(GlobalHeaderAdder globalHeaderAdder) {
return GroupedOpenApi.builder().group("v1 APIs")
// hide all v2 APIs
.pathsToExclude("/api/v2/**", "/v2/**")
// show all v1 APIs
.pathsToMatch("/api/v1/**", "/v1/**")
.addOperationCustomizer(globalHeaderAdded)
.build();
}
Edit: Answer updated with reference to #Value not providing values from application properties Spring Boot
Alternative to add and load OperationCustomizer in the case you declare yours open api groups by properties springdoc.group-configs[0].group= instead definition by Java code in a Spring Configuration GroupedOpenApi.builder().
#Bean
public Map<String, GroupedOpenApi> configureGroupedsOpenApi(Map<String, GroupedOpenApi> groupedsOpenApi, OperationCustomizer operationCustomizer) {
groupedsOpenApi.forEach((id, groupedOpenApi) -> groupedOpenApi.getOperationCustomizers()
.add(operationCustomizer));
return groupedsOpenApi;
}

How to know which message converter is used by spring boot?

For some reason I decided to change to another message converter, my code is below
#Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = new FastJsonHttpMessageConverter();
return new HttpMessageConverters(additional);
}
Now I'd like to know how to check whether this custom converter is in effect? I tried to access /beans but only got this
{
bean: "customConverters",
scope: "singleton",
type: "org.springframework.boot.autoconfigure.web.HttpMessageConverters",
resource: "com.foo.BarApplication",
dependencies: [ ]
}
So does exist some manner to know which message converter is used by spring boot?
Because I'm not very sure if my custom converter works, so I have to track source code. I cloned spring framework then attached it in eclipse, then debug step by step and found something.
In AbstractMessageConverterMethodProcessor.writeWithMessageConverters
for (HttpMessageConverter<?> messageConverter : this.messageConverters)
when watch this.messageConverters got below output
[org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter#1eb0d2e8, com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter#2026476b, org.springframework.http.converter.ByteArrayHttpMessageConverter#3287cbc7, org.springframework.http.converter.StringHttpMessageConverter#2c19dd3, org.springframework.http.converter.ResourceHttpMessageConverter#1afe28f1, org.springframework.http.converter.xml.SourceHttpMessageConverter#87129da, org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter#4a412e0, org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#a8528a2, org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter#61d720a3]
and actually it used com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter#2026476b
Only injected dependencies are shown in the dependencies array. If you do something like
#Bean
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
return new FastJsonHttpMessageConverter();
}
#Bean
#Autowired
public HttpMessageConverters convertersToBeUsed(FastJsonHttpMessageConverter converter) {
return new HttpMessageConverters(converter);
}
you will see the FastJsonHttpMessageConverter in the list.
If you want to see all registered converters, look for HttpMessageConvertersAutoConfiguration in the bean list. It should look similar to this:
{
bean: "org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration",
scope: "singleton",
type: "org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration$$EnhancerBySpringCGLIB$$9e15b021",
resource: "null",
dependencies: [
"fastJsonHttpMessageConverter",
"stringHttpMessageConverter"
]
}

Resources