4

I read few sentences of this.

I understand that simply put, the persistence layer (with its repository objects) deals with basic data access CRUD. The service layer on contains business logic. In my view, a service object contains multiples CRUD operation from one or more repository objects.

Now I was reading in a book (page 64) that it's not considered a good practice to allow presentation layer objects (such as controllers) to interact directly with repository objects.

If that is correct, it'd mean that every single simple CRUD operation of repository should have a "twin" method in service objects. Why ? Isn't that redundant ? What do we gain from doing that ?

Jason Krs
  • 179
  • 6

1 Answers1

8

The purpose of a Service Layer is to provide a layer of abstraction between your persistence layer (CRUD operations) and your presentation layer.

Given this, it is not surprising that you're finding books that say it is not a good idea for your presentation layer to interact with your repository objects directly. The whole point of the Service Layer is to shield you from having to interact directly with the database; doing so would bypass the very abstraction you seek.

If you're providing a Service Layer between your client (the presentation layer) and your database (i.e. the repository), you should be exposing methods in your Service Layer that provide services, not CRUD operations. Effectively, you can think of your Service Layer as a translator between CRUD operations and business practices.

For example, your Service Layer might expose a method called CreateInvoice(). To do that, this service method would have to look up Customer, Invoice Header, Invoice Line Item, Product and Pricing entities from your repository. It does all of this via CRUD operations. But you won't get all of those entities as a return value; rather, you're more likely to get some sort of composite ViewModel object that contains a view of all of the data required to render the invoice.

So no, you wouldn't simply pass-through your CRUD calls to the Service Layer API. Doing so is indeed redundant, and would defeat the whole purpose of having a service layer.

Further Reading
P of EAA Catalog | Service Layer

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • But what if I want to create a new customer ? The service layer will not call multiple CRUD from repository. It will call just one CRUD. Might as well use repository directly for maybe at least performance issue fro instance.This is where I see redundancy. See ? – Jason Krs Aug 25 '17 at 07:04
  • @JasonKrs No, because then you have to make the repository *visible* to the presentation layer. Also, any language implementation that has a performance problem with ~ `function makeCustomer() { persistance.makeCustomer(); }` is (almost axiomatically) not suitable for a large scale project. – Caleth Aug 25 '17 at 08:37
  • @RobertHarvey `Doing so is indeed redundant, and would defeat the whole purpose of having a service layer.` Would you then remove the abstraction despite it would expose the DAO to the view/control layer? – Laiv Aug 25 '17 at 11:01
  • @Laiv: That's essentially what Client/Server is. – Robert Harvey Aug 25 '17 at 14:41
  • @RobertHarvey, for an application that also exposes a REST API, in this case some controllers are supposed to return a resource (entity) via CRUD. Would you pass-through the CRUD calls to the service layer to avoid breaking the layered architecture or would you access directly to the repository from the controller? – Kwadz Nov 22 '17 at 10:51
  • 3
    @Kwadz: I would access the repository directly. The repository is the "service" that provides CRUD functionality; If I need CRUD functionality I will go to the repository to get it. Strict separation of layers is less important than preserving the "ignorance" of the lower layers: the repository should not know (nor should it care) who is calling it. – Robert Harvey Nov 22 '17 at 15:50