Search code examples
javaspringspring-bootdesign-patterns3-tier

3 tiers architecture best practice using Spring Boot


I work with 3-tier architecture in a Spring Boot app. I created 3 packages (model, service, controller), but what I did, service calls a repo function with try catch, and then I call it in controller

Example:

Service:

public ResponseEntity<List<Customer>> getAllCustomers() {
    try {
        List<Customer> customers = new ArrayList<Customer>();
        cutomerRepository.findAll().forEach(customers::add);
        if (customers.isEmpty()) {
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        }
        return new ResponseEntity<>(customers, HttpStatus.OK);
        } catch (Exception e) {
        return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

Controller

@GetMapping("/viewList")
private ResponseEntity<?> getAllCustomers()
{
    try{
        return customerService.getAllCustomers();
    }catch (Exception exception){
        return new ResponseEntity<String>("Customers is not found", HttpStatus.METHOD_FAILURE);

    }
}

Is that correct? I think I should put in services only customerRepository.findAll() without any other logic or code, but I'm not sure. Any idea?


Solution

  • The Service layer should contain logic, so that is OK.

    But it should not contain any classes from the Controller layer, as this would leak information from an "upper" layer into a "lower" layer. This means your Service should not return a ResponseEntity as this is from the Controller layer. Instead it should return simply a list of Customers and let the Controller construct the ResponseEntity out of it.
    Otherwise your Service will always be limited to be called by this specific Controller. It would not be reusable to be called by another service of a different type of Controller, that does not use an HTTP ResponseEntity.