Is it possible to implement AlternateTypeRules functionallity with annotation? - spring

I've got following issue - https://github.com/springfox/springfox/issues/2373 and I fixed it with the following code:
#Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.alternateTypeRules(AlternateTypeRules.newRule(TestCarResource.Car.Id.class, String.class));
}
Can I mark my Car.Id class with any annotation to remove this boilerplate code?

Related

Swagger Models for Throwable and StackTraceElement

Swagger UI shows Models for StackTraceElement and Throwable objects.
I would like to configure it so that these models are not shown.
I have tried annotating the custom class for exceptions with #JsonIgnore:
/** Custom exception class to handle business validation exceptions. */
#JsonIgnoreProperties({"detailMessage", "cause", "stackTrace", "suppressed"})
public class PatientBundleException extends Exception {
#JsonIgnore
public PatientBundleException(String exceptionMessage) {
super(exceptionMessage);
}
}
Here is my Docket:
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("..."))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
I am using springfox version 2.9.2
If anyone can help assist with configuring Swagger UI to not show models for Throwable and StackTraceElement, that would be much appreciated!
I fixed the issue, it turns out I was extending "Exception" on my model, when I didn't need to.

How set SpringFox to show two (or more) versions of the Rest API using Spring Boot?

I'm trying to figure out how manage two (or more) version of my API endpoints using Spring Fox.
To version my APIs, I'm using the Versioning through content negotiation, also know as Versioning using Accept header. The versions of each endpoint are controlled individually using the header information. Per example, for the version one I use the attribute produces:
#Override
#PostMapping(
produces = "application/vnd.company.v1+json")
public ResponseEntity<User> createUser(
For version two, I use:
#Override
#PostMapping(
produces = "application/vnd.company.v2+json",
consumes = "application/vnd.company.v2+json")
public ResponseEntity<User> createUserVersion2(
I not use consumes for the first (v1) version, so if the client use only application/json on the call the first version will be called by default.
I would like to show the two version on the Swagger UI. How to do that?
It's very simple. Just create one Docket for each version.
Example, the first version:
#Bean
public Docket customImplementation(
#Value("${springfox.documentation.info.title}") String title,
#Value("${springfox.documentation.info.description}") String description) {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo(title, description, "1.0"))
.groupName("v1")
.useDefaultResponseMessages(false)
.securitySchemes(newArrayList(apiKey()))
.pathMapping("/api")
.securityContexts(newArrayList(securityContext())).select()
.apis(e -> Objects.requireNonNull(e).produces().parallelStream()
.anyMatch(p -> "application/vnd.company.v1+json".equals(p.toString())))
.paths(PathSelectors.any())
.build();
}
And for version two:
#Bean
public Docket customImplementationV2(
#Value("${springfox.documentation.info.title}") String title,
#Value("${springfox.documentation.info.description}") String description) {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo(title, description, "2.0"))
.groupName("v2")
.select()
.apis(e -> Objects.requireNonNull(e).produces()
.parallelStream()
.anyMatch(p -> "application/vnd.company.v2+json".equals(p.toString())))
.build();
}
The secret here is filter the available endpoints by the produces attribute.
The Swagger-UI will show the two versions on the combo:
This code needs to be on a class annotated with #Configuration. You also need to enable the Swagger with #EnableSwagger2.
As mentioned by Dherik you can create Docket for each version. But to filter here I have tried using Predicate and custom controller annotations.
Configuration class annotated with #Configuration and #EnableSwagger2
import com.google.common.base.Predicate;
#Bean
public Docket apiV30() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("v30")
.select()
.apis(selectorV30())
.paths(PathSelectors.any()).build().apiInfo(apiEndPointsInfo());
}
private Predicate<RequestHandler> selectorV30(){
return new Predicate<RequestHandler>() {
#Override
public boolean apply(RequestHandler input) {
return input.findControllerAnnotation(SwaggerDocV30.class).isPresent();
}
};
}
#Bean
public Docket apiV31() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("v31")
.select()
.apis(selectorV31())
.paths(PathSelectors.any()).build().apiInfo(apiEndPointsInfo());
}
private Predicate<RequestHandler> selectorV31(){
return new Predicate<RequestHandler>() {
#Override
public boolean apply(RequestHandler input) {
return input.findControllerAnnotation(SwaggerDocV31.class).isPresent();
}
};
}
Custom Annotation class : SwaggerDocV30
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface SwaggerDocV30 {
}
Custom Annotation class : SwaggerDocV31
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface SwaggerDocV31 {
}
Finally annotate your controllers with #SwaggerDocV30 or #SwaggerDocV31
#SwaggerDocV30
#Controller
public class MyController extends AbstractController {}
Or
#SwaggerDocV31
#Controller
public class MyController extends AbstractController {}]

Support multiple pathmapping in Swagger UI/Spring boot

I am using swagger 2.0 in a Spring boot(version 1.5.9.RELEASE) project.
Swagger works fine but now documentation have hundreds of api and I want to redirect documentation on different different urls.I am having swagger configuration like blow.
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket postsApi() {
return new Docket(DocumentationType.SWAGGER_2).groupName("public-api")
.apiInfo(apiInfo()).select().paths(postPaths()).build();
}
private Predicate<String> postPaths() {
return or(regex("/api/posts.*"), or(regex("/api/.*"), regex("/secure/api/.*")));
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Swagger API")
.description("Swagger Integration with Spring Boot")
.termsOfServiceUrl(null)
.license(null)
.licenseUrl(null).version("1.0").build();
}
}
Please suggest any way. Thanks in advance.
Finally I break these api's into groups basis on their url as following code segment, creates three group one for Settings, another for Products and last one contains all the other documentation except settings and products.
#Bean
public Docket swaggerSettingsApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Settings")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xyz"))
.paths(regex("/secure/api/v1/settings/.*"))
.build()
.apiInfo(new ApiInfoBuilder().version("1.0").title("Settings API").build())
.globalOperationParameters(operationParameters());
}
#Bean
public Docket swaggerProductApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Product")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xyz.modules.v1"))
.paths(productPaths())
.build()
.apiInfo(new ApiInfoBuilder().version("1.0").title("Product API").build())
.globalOperationParameters(operationParameters());
}
#Bean
public Docket swaggerModuleApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Others")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xyz.modules.v1"))
.paths(postPaths())
.build()
.apiInfo(new ApiInfoBuilder().version("1.0").title("Other Modules API").build())
.globalOperationParameters(operationParameters());
}
private Predicate<String> postPaths() {
return or(regex("^(?=\\/secure\\/api\\/v1\\/)(?!.*(settings|products)).+\\/.*"));
}

Swagger2 not dispaying the documentation is UI format

I have RESTful web service which I have developed in spring boot. I have integrated the swagger2 in my application using Gradle build tool.
testCompile('io.springfox:springfox-swagger2:2.6.1')
testCompile('io.springfox:springfox-swagger-ui:2.6.1')
I wrote the configuration file for swagger2 in following way
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select().apis(RequestHandlerSelectors.basePackage("com.example.restdemo.web"))
.paths(PathSelectors.any())
.build();
}
}
Now when I try to access the http://localhost:8080/v2/api-docs I am getting the JSON string. But when I am trying to access the http://localhost:8080/swagger-ui.html I am not getting Swagger UI view, I am getting the 406 error.
Did you try like this?
http://localhost:8080/swagger-ui.html#!/test-controller/
Here Controller class name is TestController
Also, replace
.select().apis(RequestHandlerSelectors.basePackage("com.example.restdemo.web"))
with
.select()
As below..
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
Can you try below Swagger configurations? basePackage is nothing but the entry point of your rest API layer. You can hardcode it in your program.
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
UiConfiguration uiConfig() {
return new UiConfiguration("validatorUrl", "list", "alpha", "schema",
UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS, false, true, 60000L);
}
}

Hide return value from a Spring MVC controller in SpringFox 2

I have an async Spring MVC controller that returns Future. SpringFox 2 renders it as this:
How do I remove it? Thank you in advance!
I resolved the issue by adding the following method call to SprinfFox's Docket:
.genericModelSubstitutes(ResponseEntity.class, CompletableFuture.class)
Hope it will help someone.
It does not work with types.
So, let's suppose that this is the controller method:
public CompletableFuture<ResponseEntity<ResponseDTO>> getDTO() {
return CompletableFuture.completedFuture(ResponseEntity.ok(new ResponseDTO());
}
Adding just the configuration:
.genericModelSubstitutes(ResponseEntity.class, CompletableFuture.class)
.directModelSubstitute(CompletableFuture.class, java.lang.Void.class)
it will not work. The method needs to be modified to:
public CompletableFuture getDTO() {
return CompletableFuture.completedFuture(ResponseEntity.ok(new ResponseDTO());
}
Then the CompletableFuture definition will disappear from OpenAPI specs.
Found a better approach. I'm using springfox version 2.8.0. If you have a look at their docs (RTFM) you can have type classes resolved to POJO using a type adapter. An example for this configuration is like this:
import com.fasterxml.classmate.TypeResolver;
#Configuration
#EnableSwagger2
public class SpringFoxConfig {
#Autowired
private TypeResolver typeResolver;
#Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("base package"))
.paths(PathSelectors.any())
.build()
.genericModelSubstitutes(ResponseEntity.class)
.alternateTypeRules(
newRule(typeResolver.resolve(CompletableFuture.class,
typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
typeResolver.resolve(WildcardType.class)))
.useDefaultResponseMessages(false)
.pathMapping("/");
}
And the controller method can be defined with types:
public CompletableFuture<ResponseEntity<ResponseDTO>> getDTO() {
return CompletableFuture.completedFuture(ResponseEntity.ok(new ResponseDTO());
}

Resources