0

In my Maven, Spring Boot 2 project I have Maven module called api1. I have declared a number of @RestControllers there.

In order to extend the logic of the api1 module, I have implemented another Maven module called api2 and placed api1 there as Maven dependency.

Right now all of the @RestControllers from api1 project are initialized in the api2 because all of them are present on the api2 classpath.

How to disable a certain @RestController in api2 project?

6
  • What do you mean by @RestControllers' from api1` project are initialized in the api2? Commented Mar 22, 2018 at 7:15
  • I mean that all @RestControllers' classes from api1 project are up and running(exposes as HTTP API in my web project) in api2 project. I want to disable some of them in api2. Commented Mar 22, 2018 at 7:18
  • disable mean Not Accessible like public and private? Commented Mar 22, 2018 at 7:21
  • do not exposed as API at all, like for example when it is completely absent in the classpath Commented Mar 22, 2018 at 7:24
  • you can just remove @RestController annotation from those controllers and they will no longer be treated as Controller in your application. Commented Mar 22, 2018 at 7:25

2 Answers 2

2

You may try using Condition interface from Spring which provide support for conditional enable/disable of the beans based on certain condition/expression.

something like below:

@RestController
@ConditionalOnExpression("${api1.controller.enabled:false}")
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class Api1Controller {
    @RequestMapping(value = "/greeting")
    public ResponseEntity<String> greeting() {
        return new ResponseEntity<>("Hello world", HttpStatus.OK);
    }
}

you have to set the Conditional expression by some way (env. variable / property key). check this for some reference. Condition docs can guide you on more details.

Sign up to request clarification or add additional context in comments.

Comments

1

I think the crucial fact here to understand is that Spring works at runtime only, while maven matters in build time.

So maven sees that api2 depends on api1 so it understands that both modules have to be included in the artifact (in the case of spring boot its a big jar with all modules inside).

Now, when spring starts - it "takes for granted" that all modules are accessible, and depending on spring configurations it just defines beans to be loaded and processed, all rest controllers are among these beans of course.

So I assume, you don't mind having two modules in the artifact (and in classpath).

In this case, you shouldn't touch the maven part at all, but when the spring boot application starts it has to be "instructed" somehow that some rest controllers have to be excluded. The point is that it should be done not in terms of modules ("hey, spring, this controller belongs to module api2, so it has to be excluded"), but in terms of business "jargon". For example, api1 contains all "admin" functionality and api2 contains all "applicative" stuff. So, if you work with Java configurations, for example, you can do the following:

Inside module api1:

@Configuration
@ConditionalOnProperty(name = "admin.enabled", havingValue=true)
public class AdminControllersConfiguration {

   @Bean 
   public AdminControllerFromModuleApi1 adminController() {
      return new AdminControllerFromModuleApi1();
   }
}

}

In module api2 you just define your rest controllers in a similar way but without "@ConditionalOnProperty" annotation.

The thing with this annotation is that it allows to "switch off" beans or entire configurations like in my example.

So, when you start api2, you just define in "application.properties" or something the following:

admin.enabled=false

And your controllers won't be "deployed" by spring although physically the files are certainly in the classpath.

Of course, since spring allows different types of configurations, this method might not be applicable to your project, but the idea is still the same.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.