4

Ideally, controllers in a Spring MVC application must receive a request, despatch the request to an API, load the results (of the invocation) on to the model (for the view to subsequently render it) and forward to a view. They should do no more.

My controllers do far more than this today and I would like to move certain resposibilities away from the controller on to other APIs. My application design today (pretty typical):

controller <-> Service API <-> DAO <-> DB

The controller today fills up the delta between what the web app needs and what the Service API delivers. I would like to place extra layer/layers between the controller and service API that chew away at this delta. My question is what layer(s) should these be and what should the responsibilities of these new layer(s)?

My current Idea is as follows

controller <-> controller helper <-> Business API <-> Service API <-> DAO <-> DB

Controller helper (web context aware - will depend on Model, HttpServlet and other web context classes):

  1. Convert entities to DTO objects (2 way)
  2. Resolve IDs to entities. E.g. Controller looks up a student i.d. (using a key) and converts it to a Student entity.

Business API (no web context dependency - can be JUnit tested):

  1. Acts as a Facade. Invoking multiple service APIs to achieve one business request.
  2. Providing APIs that are specifically tailered for the web app.

Would you solve this a different way? Are there any resources (books, articles etc...) relating to this specific issue?

Some of previous discussions that did not answer my question:

Designing mvc controller layer

Service layer = Application layer = GRASP Controller layer

Moving Validation, Html Helpers to Service Layer in MVC

Thanks, Vijay

Community
  • 1
  • 1
Babu Subburathinam
  • 2,474
  • 2
  • 23
  • 22

2 Answers2

2

Services contain the general business logic of an application. They are pretty much anything between Controllers and DAO/DB.

Your "business layer" and "controller helper" are just more services. I would keep the classic design for the sake of simplicity :

Controllers <-> possible Services <-> possible DAOs <-> DB

If I had lots of services (I usually don't) that happened to perform the same kind of logic, I would naturally split them into sub-packages. For example :

  • services.facade, or services.business
  • services.adapter for DTOs (except if you use simple classes to do this job)

A facade service is called by controllers like so : someFacade.someMethod(SomeDTO someDto). Then the facade handles DTO <-> Entity conversion thanks to other services (or simple classes).

That's how I would do in your context. In an ideal world (no legacy systems, or in a project from scratch), I'd directly use entities as form objects (instead of DTOs), and most of my services would be facades (the rest would be simple classes, if possible).

Jerome Dalbert
  • 10,067
  • 6
  • 56
  • 64
0

I'm new to Spring MVC and am also faced with this dilemma. Although Spring is new to me, I've been working with MVC for several years. I agree a controller should do no more than accept requests, dispatch them, and render the results in the correct format. I'm of the opinion that a service isn't necessarily the best place for the helper abstraction to exist though. I believe a service should encapsulate a specific API and do nothing more. I feel creating many 'types' of services convolutes this pattern and makes it unclear where the responsibilities fall.

It's my belief that helpers are better suited as siblings to services; they should be decorated with @Component instead of @Service. Their role is to act as a facade for the underlying APIs that are needed to transition state on the models exposed through the endpoint. The Controller->Helper->[Services] pattern promotes a clear separation of concerns, code-reusability, and is highly testable. The nature of this pattern is to prevent controller bloat, so you end up with ultra-thin controllers that really do nothing more than dispatch requests and render responses.

Kevin
  • 150
  • 3
  • 7