5

I have a few layers in my WebApplication: Presentation, Service, DAO, Domain.

Services call DAO objects which reads data from a Database/File whatever.

I have a Controller that needs to fetch data from different Services and set them as part of the Response.

Should I put the logic to call different Services in the Controller method or should I create some sort of Facade which in turn will call different Services? If so, in what Layer should the Facade reside?

@Path("/")
public class MyController {

  @Autowired
  private FirstService firstService;

  @Autowired
  private SecondService secondService;

  @GET
  public Response getData(@QueryParam("query") final String query) {
      final MyResponse response = new MyResponse();

      // Service 1
      final String firstData = firstService.getData(query);
      response.setFirstData(query);


      if (someCondition) {
        // Service 2
        final String secondData = secondService.getData(query);
        response.setSecondData(query);
      }

      // more Service calls maybe

      return Response.status(Response.Status.OK).entity(response).build();
  }

}
  • 1
    Related stackoverflow question. Personally I think your current code is fine. – avik Apr 25 '16 at 12:06
  • 1
    Yes. It's dispatching business what fits well into Controller purpose. I would not do what @lJoSeTe4ever suggest. That way is mixing up 2 services into 2 by its URL. It's coupling services. So far, your solution is fine, If you don't want to do such if/else I suggest to you to implement a Broker. Broker has all the service and it does the choice instead of doing it at MyController. Broker is like a global Service which concentrate all others into the same point. Depends on how many times you have to do the same if/else – Laiv Apr 25 '16 at 13:18
4

In my humble opinion, the controller should be the "facade" itself, that means that the controller should decide which service to call, and the services should be in charge of generating the response object.

What I would do is to define a method per action, and discriminate the service using REST naming, something like this:

@Path("/")
public class MyController {

  @Autowired
  private FirstService firstService;

  @Autowired
  private SecondService secondService;

  @RequestMapping(value = "/service1/{query}", method = {RequestMethod.GET})
  public Response getData(@RequestParam("query") final String query) {

      return firstService.yourMethod(); // inside the service you handle the response.
  }

  @RequestMapping(value = "/service2/{query}", method = {RequestMethod.GET})
  public Response getData(@RequestParam("query") final String query) {

      return secondService.another(); // inside the service you handle the response.
  }

}
  • I don't think mixing up 2 services into 2 through its url is a good idea. If they are 2 independent services, then make 1 controller per Service. Even if they have the very same interface/features/urls/whatever. Plus you are placing the choice of which one to use at client-side. So you are placing a business choice into client-side, what means (in the worst scenario), 2 calls and your business scatered in 2 facades – Laiv Apr 25 '16 at 13:23
  • MVC pattern it self is a pattern. Controller should not be restricted to call one service. If Controller is restricted to call one service, then that service might have a chance to have two responsibility, which will disobey "single responsibility principle". – Young Hyun Yoo Feb 4 '18 at 9:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.