Why do we need to call Service layer using Interface instead of direct service class from controller in spring - spring

When spring was introduced its advice to use an interface between different layers like Controller,Service,DAO instead of directly calling them using actual class reference.
In new age of Spring 5.x and Spring Boot 2.x do we need to still use interface between Controller and Service class. In my case I am developing a REST application with single GET method which call DB and do some business logic. So In my service I have only one method in this case still I do need to use ServiceInterface to call my actual ServiceImpl? what is best practice and is there any specific advantage of using ServiceInterface in this scenario?
Below is Sample code without ServiceInterface
public class MyTestController{
private MyTestServiceImpl myTestServiceImpl;
public MyTestController(MyTestServiceImpl myTestServiceImpl){
this.myTestServiceImpl = myTestServiceImpl;
}
#GetMapping("/test")
public String getTestString(){
myTestServiceImpl.getTestString();
}
}
#Service
public class MyTestServiceImpl(){
private MyTestRepository myTestRepository;
//constructor
//Service method impl
}

In very small applications, it doesn't really matter, because it is still very easy to keep track of all the classes and what classes do what. In a large scale enterprise application it can quickly become a cluttered mess. For example, if you have a rest endpoint/controller that has 100 methods, and it in turn calls 50 methods in your DAO. If you at some point decide to change the DAO methods, you will now have to change all 100 methods in the controller/endpoint. Whereas if you have a service layer in between to bridge the DAO and rest controller you only have to change the service methods.
Another point as #p.streef has mentioned is the seperation of classes and their functions. You can have a modular application wherein the service layer handles all the business logic and rules, the DAO is only responsible for database operations and the controller's only job is to send and receive data. The S in S.O.L.I.D stands for Single responsibility principle, so instead of the service layer is supposed to handle only receiving and transmitting data, and not business logic.
However, if you are building a very very small application then it shouldn't matter.

Related

If Service returns DTO not entity, how to handle DTO in other service in Spring Boot?

After reading this article, I change return value of service method entity into DTO.
But I'm little confused in this below situation.
Entity A <- Repository A <- Service A
Entity B <- Repository B <- Service B
Then , If Service B need to access entity A ,so call method in Service A. Since the result of that method is DTO ,not entity, I'm having a hard time dealing with DTO A in Service B.
Should I call repository A in Service B? or should I call Service A in Service B and use modelmapper to covert dto to entity in service B?
// Controller code
#RestController
public FooDTO getSomeFoo(){
return new FooDTO(service.getFoo())
}
// Service code
#Service
public Foo getFoo(){
return repository.find(~)
}
In my opinion, unless you really want to protect your entities to be changed elsewhere other than the corresponding Service, I would avoid DTOs in calls inside the service layer. This means that it is ok to return Entities in methods that you know that are called by other Services in your application, unless you really want to, most probably, over-engineer your application.
Having said that you should return DTOs only in the methods that are called by your Controller layer so that they are used in your REST API (assuming you have one).
Of course, this requires discipline and making sure you don't call methods on your Controller that are supposed to be called only by Services. There is an architecture that tries to tackle this (if you want to read more about it --> https://medium.com/#shivendraodean/software-architecture-the-onion-architecture-1b235bec1dec) and you can try to take advantage of package protected feature to guarantee this.
Should I call repository A in Service B?
Definitely not. You should never (never may be a strong word, but you should at least strive hard to avoid it) do this, otherwise your code will turn into a complete mess without any structure whatsoever.

Identifying Spring MVC architecture pattern

I'm working through a spring mvc video series and loving it!
https://www.youtube.com/channel/UCcawgWKCyddtpu9PP_Fz-tA/videos
I'd like to learn more about the specifics of the exact architecture being used and am having trouble identifying the proper name - so that I can read further.
For example, I understand that the presentation layer is MVC, but not really sure how you would more specifically describe the pattern to account for the use of service and resource objects - as opposed to choosing to use service, DAO and Domain objects.
Any clues to help me better focus my search on understanding the layout below?
application
core
models/entities
services
rest
controllers
resources
resource_assemblers
Edit:
Nathan Hughes comment clarified my confusion with the nomenclature and SirKometa connected the architectural dots that I was not grasping. Thanks guys.
As far as I can tell the layout you have mentioned represents the application which communicates with the world through REST services.
core package represents all the classes (domain, services, repositories) which are not related to view.
model package - Assuming you are aiming for the typical application you do have a model/domain/entity package which represents your data For example: https://github.com/chrishenkel/spring-angularjs-tutorial-10/blob/master/src/main/java/tutorial/core/models/entities/Account.java.
repository package - Since you are using Spring you will most likely use also since spring-data or even spring-data-jpa with Hibernate as your ORM Library. It will most likely lead you to use Repository interfaces (author of videos you watch for some reason decided not to use it though). Anyway it will be your layer to access database, for example: https://github.com/chrishenkel/spring-angularjs-tutorial-10/blob/master/src/main/java/tutorial/core/repositories/jpa/JpaAccountRepo.java
service package will be your package to manipulate data. It's not the best example but this layer doesn't access your database directly, it will use Repositories to do it, but it might also do other things - it will be your API to manipulate data in you application. Let's say you want to have a fancy calculation on your wallet before you save it to DB, or like here https://github.com/chrishenkel/spring-angularjs-tutorial-10/blob/master/src/main/java/tutorial/core/services/impl/AccountServiceImpl.java you want to make sure that the Blog you try to create doesn't exist yet.
controllers package contain all classes which will be used by DispacherServlet to take care of the requests. You will read "input" from the request, process it (use your Services here) and send your responses.
resource_assemblers package in this case is framework specific (Hateoas). As far as I can tell it's just a DTO for your json responses (for example you might want to store password in your Account but exposing it through json won't be a good idea, and it would happen if you didn't use DTO).
Please let me know if that is the answer you were looking for.
This question may be of interest to you as well as this explanation.
You are mostly talking about the same things in each case, Spring just uses annotations so that when it scans them it knows what type of object you are creating or instantiating.
Basically everything request flows through the controller annotated with #Controller. Each method process the request and (if needed) calls a specific service class to process the business logic. These classes are annotated with #Service. The controller can instantiate these classes by autowiring them in #Autowire or resourcing them #Resource.
#Controller
#RequestMapping("/")
public class MyController {
#Resource private MyServiceLayer myServiceLayer;
#RequestMapping("/retrieveMain")
public String retrieveMain() {
String listOfSomething = myServiceLayer.getListOfSomethings();
return listOfSomething;
}
}
The service classes then perform their business logic and if needed, retrieve data from a repository class annotated with #Repository. The service layer instantiate these classes the same way, either by autowiring them in #Autowire or resourcing them #Resource.
#Service
public class MyServiceLayer implements MyServiceLayerService {
#Resource private MyDaoLayer myDaoLayer;
public String getListOfSomethings() {
List<String> listOfSomething = myDaoLayer.getListOfSomethings();
// Business Logic
return listOfSomething;
}
}
The repository classes make up the DAO, Spring uses the #Repository annotation on them. The entities are the individual class objects that are received by the #Repository layer.
#Repository
public class MyDaoLayer implements MyDaoLayerInterface {
#Resource private JdbcTemplate jdbcTemplate;
public List<String> getListOfSomethings() {
// retrieve list from database, process with row mapper, object mapper, etc.
return listOfSomething;
}
}
#Repository, #Service, and #Controller are specific instances of #Component. All of these layers could be annotated with #Component, it's just better to call it what it actually is.
So to answer your question, they mean the same thing, they are just annotated to let Spring know what type of object it is instantiating and/or how to include another class.
I guess the architectural pattern you are looking for is Representational State Transfer (REST). You can read up on it here:
http://en.wikipedia.org/wiki/Representational_state_transfer
Within REST the data passed around is referred to as resources:
Identification of resources:
Individual resources are identified in requests, for example using URIs in web-based REST systems. The resources themselves are conceptually separate from the representations that are returned to the client. For example, the server may send data from its database as HTML, XML or JSON, none of which are the server's internal representation, and it is the same one resource regardless.

Spring DTO validation in Service or Controller?

I'm building a straight forward AJAX / JSON web service with Spring. The common data flow is:
some DTO from browser
v
Spring #Controller method
v
Spring #Service method
I'm looking for the most easy way to handle data validation.
I know the #Valid annotation which works pretty well inside #Controller methods.
Why does #Valid not work within #Service methods?
I mean: A service method can be used by any other service and controller. So wouldn't it make much more sense to validate at #Service level?
Let's take this simple example:
MyDTO.java:
public class MyDTO {
#NotNull
public String required
#Min(18)
public int age;
}
MyServiceImpl.java:
public MyDomainObject foo(MyDTO myDTO) {
// persist myDTO
// and return created domain object
}
MyController.java:
#Autowired
MyService myService;
#Autowired // some simple bean mapper like Dozer or Orika
Mapper mapper; // for converting domain objects to DTO
#RequestMapping(...)
public MyDomainObjectDTO doSomething(#RequestBody MyDTO myDTO) {
mapper.map(myService.foo(myDTO), MyDomainObjectDTO.class);
}
Is it common practice that the service method receives the DTO?
If yes: What's the best practice to validate that DTO inside the service method?
If no: Should maybe the controller manipulate the Domain object and just let the service save that object? (this seems pretty useless to me)
In my opinion the service should be responsible for only data consistency.
How do you solve this?
My answer? Both.
The service must check its own contract for validity.
The controller is part of the UI. It should validate and bind for a better user experience, but the service should not rely on it.
The service cannot know how it's being called. What if you wrap it as a REST service?
The service also knows about business logic violations in a way that no UI can. It needs to validate to make sure that the use case is fulfilled appropriately.
Double bag it; do both.
See my other answer: Check preconditions in Controller or Service layer
If you really want to do validation like error handling in your Service layer similar to Spring MVC you can use javax.validation and AspectJ (to advice the methods to validate) which is what I do because I like making reflection do the work and declarative programming (annotations).
Spring MVC doesn't need to do AspectJ/AOP to do the error handling because the methods are being called through reflection (url routing/dispatching).
Finally for you MVC code you should know that #Valid is sort of unofficially deprecated. Instead consider #Validated which will leverage more of the javax.validation features.

How to manage transactions with JAX-RS, Spring and JPA

I'm using JAX-RS to provide an HTTP-based interface to manage a data model. The data model is stored in a database and interacted with via JPA.
This allows me to modify the interface to the data model to suit REST clients and mostly seems to work quite well. However, I'm not sure how to handle the scenario where a method provided by a JAX-RS resource requires a transaction, which affects the JPA get, update, commit-on-tx-end pattern, because there is only a transaction wrapping the get operation, so the update is never committed. I can see the same problem occurring if a single REST operation requires multiple JPA operations.
As I'm using Spring's transaction support, the obvious thing to do is to apply #Transactional to these methods in the JAX-RS resources. However, in order for this to work, Spring needs to manage the lifecycle of the JAX-RS resources, and the useage examples I'm aware of have resources being created via `new' when needed, which makes me a little nervous anyway.
I can think of the following solutions:
update my JPA methods to provide a transaction-managed version of everything I want to do from my REST interface atomically. Should work, keeps transactions out of the JAX-RS layer, but prevents the get, update, commit-on-tx-end pattern and means I need to create a very granular JPA interface.
Inject Resource objects; but they are typically stateful holding at least the ID of the object being interacted with
Ditch the hierarchy of resources and inject big, stateless super resources at the root that manage the entire hierarchy from that root; not cohesive, big services
Have a hierarchy of injected, stateless, transaction-supporting helper objects that 'shadow' the actual resources; the resources are instantiated and hold ths state but delegate method invocations to the helper objects
Anyone got any suggestions? It's quite possible I've missed some key point somewhere.
Update - to work around the lack of a transaction around the get, update, commit-on-tx-close flow, I can expose the EntityManager merge(object) method and call it manually. Not neat and doesn't solve the larger problem though.
Update 2 #skaffman
Code example:
In JPA service layer, injected, annotations work
public class MyEntityJPAService {
...
#Transactional(readOnly=true) // do in transaction
public MyEntity getMyEntity(final String id) {
return em.find(MyEntity.class, id);
}
In JAX-RS resource, created by new, no transactions
public class MyEntityResource {
...
private MyEntityJPAService jpa;
...
#Transactional // not injected so not effective
public void updateMyEntity(final String id, final MyEntityRepresentation rep) {
MyEntity entity = jpa.getMyEntity(id);
MyEntity.setSomeField(rep.getSomeField());
// no transaction commit, change not saved...
}
I have a few suggestions
Introduce a layer between your JPA and JAX-RS layers. This layer would consist of Spring-managed #Transactional beans, and would compose the various business-level operations from their component JPA calls. This is somewhat similar to your (1), but keeps the JPA layer simple.
Replace JAX-RS with Spring-MVC, which provides the same (or similar) functionality, including #PathVariable, #ResponseBody, etc.
Programmatically wrap your JAX-RS objects in transactional proxies using TransactionProxyFactorybean. This would detct your #Transactional annotations and generate a proxy that honours them.
Use #Configurable and AspectJ LTW to allow Spring to honour #Transactional even if you create the object using `new. See 8.8.1 Using AspectJ to dependency inject domain objects with Spring

good practice mvc with spring

with spring, when we have a service layer, dao layer and controller to manage a form data (list, selected list value, data found by the bd)
is it a good practice to put all this data in a object?
is a good practice to create a method in the service layer who will call many dao method to feed listbox... and feed a ford object or it's better
to call different method in the service layer from the controller ?
public class UserForm {
private SearchCritera searchCritera;
private List<String> city;
private List<String> country;
...
}
public class SearchCritera {
private List<String> selectedCity;
private List<String> selectedCountry;
...
}
maybe there are a better way that the two idea I proposed?
To me, it makes more sense to have what you suggested:
a DAO layer where you access the database with single operations
a service layer where you aggregate calls to the DAO layer and do some business logic
a web / controller layer where you make calls to the service layer and do what is necessary for the view to be rendered.
Keep in mind that either way you're designing your application, you have to configure it so that the transactions are dealt with properly. If your service layer is transactionnal and there are multiple calls from the web layer within the same method to the service layer, then if something goes wrong, likely the database might not end up in a clean state.
What you want to avoid too is to have business logic in your controller layer.

Resources