15

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();
  }

}

2 Answers2

11

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

}
-1

I believe that a controller method should not have any logic inside. It may control data suitability and do some security things. And in your case you don't have to split your controller method to two other methods. Instead you can call a servis that is "only responsible for" setting params or preparing response which is not breaks single responsibilty rule and you give the decision of setting paramTwo to this service method.

@GET
  public Response getData(@QueryParam("query") final String query) {
      return prepareResponseService.createResponse(query);
  }

Method and service namings are up to you.

public Response createResponse(final String query) {
    final MyResponse response = new MyResponse();
final String firstData = firstService.getData(query);
response.setFirstData(query);

final String secondData = secondService.getData(query); // handle your condition in secondService
response.setSecondData(query);

return response;

}

Oguz
  • 1