How to set multi controller's package base to my SwaggerConfiguration?

Viewed 1809

My dependency....

<!-- SPRING BOOT -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>


My problem happen when i tried to use in swagger two packages base. Below you can see what i mean with package base and above you can see my dependency. My code that i tried to use two package base are more below.

aPackageBase: com.companyx
bPackageBase: br.com.companyz

Things that I cannot do

  • I cannot change the package base because they are huge APIs.
  • I have more then 10 APIs that follow that 2 package base.
  • I would like to use aPackageBase and bPackageBase.

Current code, that is not working...

...
String aPackageBase = "com.companyx";
String bPackageBase = "br.com.companyz";

Docket docket = new Docket(DocumentationType.OAS_30).select() //
    .apis(RequestHandlerSelectors.basePackage(aPackageBase) //
        .and(RequestHandlerSelectors.basePackage(bPackageBase))) // That doesn't work :(....
        .paths(PathSelectors.any()).build()

...

What would like to have...

I just want to use both packages base. I am not trying to change the at runtime, of course I can change it at runtime and use only one packageBase, but I am tired to change it for each API. If I can have aPackageBase and bPackageBase it will save my life. haaha.


Note: I don't think I need show more about my SwaggerConfiguration because my problem is only in that part.

2 Answers

You need to change your Docket bean definition a little bit.

Docket docket = new Docket(DocumentationType.OAS_30)
    .select() //
    .apis(RequestHandlerSelectors.basePackage(aPackageBase) //
        .or(RequestHandlerSelectors.basePackage(bPackageBase))) // use or here, not and
    .paths(PathSelectors.any())
    .build();

RequestHandlerSelectors.basePackage(...) returns a java.util.function.Predicate object.

Predicate#and requires both condition to be true, which is not, since any API will exist in one of the packages only. Hence Predicate#or.

Pratapi's answer is the right one. But if you are using an older version of springfox, the basePackage returns a Google Guava predicate (link).

Note that the Google Guava predicate extends the Java predicate and the or method is not overriden in the Guava Predicate. Hence, calling or will return a Java predicate. You can use a method reference (or a lambda expression) to pass a Guava predicate to the apis method.

//A java.util.function.Predicate
Predicate<RequestHandler> predicate = RequestHandlerSelectors.basePackage(aPackageBase)
          .or(RequestHandlerSelectors.basePackage(bPackageBase));

return docket.select()
           .apis(predicate::test) //.apis(r -> p1.test(r))
           ....
Related