noNihongo
noNihongo

Reputation: 188

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

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


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.

Upvotes: 5

Views: 5387

Answers (3)

Jayesh.Gehlod
Jayesh.Gehlod

Reputation: 1

Below code snippet worked for me for swagger2:

List<Predicate<RequestHandler>> predicateList = new ArrayList<>();
predicateList.add(RequestHandlerSelectors.basePackage(com.sample.one));
predicateList.add(RequestHandlerSelectors.basePackage(com.sample.two));

Docket d = new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(Predicates.or(predicateList))
                .paths(PathSelectors.any())
                .build().forCodeGeneration(true)
                .securitySchemes(Arrays.asList(oAuthSecurityScheme()));

Upvotes: 0

Thiyagu
Thiyagu

Reputation: 17880

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))
           ....

Upvotes: 3

Hemant Patel
Hemant Patel

Reputation: 3260

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.

Upvotes: 10

Related Questions