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

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.

Related

How naming objects returned by Controllers, Service and Repositories?

In Spring MVC we have 3 main categories of objects: Controllers, Services and Repositories.
I'm not able to "categorize" the objects returned by these three categories.
For example, the repositories return Entitys, but how could I name the objects returned by services and controllers?
In a real project I'm developing I have a repository returns an extraction from a table, so I get Entities objects. Into the service, where the logic is, I need only to return some fields, so I need to map the entities to another object-model. Later into the controller maybe I will need some layer specific presentation, for example between "standard-computer" and mobile, so I need another type of object to map the result of the service.
Each layer has its postfix in the name of the class to keep the codebase clean and readable. In most of the projects I have worked on, the naming convention is:
Controller layer
The POJO exposed outside of the application, for example, thought a REST API is DTO (Data Transfer Object), so it is usually under the dto package, and the name is like UserDto
Service layer
The POJO that handles the application's business logic is called domain object, so it is usually under the domain package, and the name is like User without any postfix in the name.
Repository layer
The POJO that holds the data in the persistence layer is called entity, so it is usually under the jpa package, and the name is like UserJpa

Why do we need to call Service layer using Interface instead of direct service class from controller in 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.

Should marshal/demarshaling be in service (transactional) methods or controller in spring boot project?

I am working on spring boot application with CRUD api with input and output as json object. Is it okay to include json->POJO and POJO->json logic in service method? (service method is marked with transactional annotation)
//Controller
public Map<String, String> getPersonNames(){
return personSvc.getNames();
}
//Service method
#Transactional(readonly = true)
public Map<String, String> getNames(){
return populateNames(repo.findAll());
}
private Map<String, String> populateNames(final List<Person> personList) {
return ImmutableMap.of(
//Populate names into map
);
}
Well, it mostly depends on application you are building.
Based on the information you provided (almost no information) I can only speak in general, but there is a Domain Driven Design (DDD), which is quite common for Spring applications. You can find more info in answers to this question
This kind of design separates your core domain logic from logic that your technological stack forces you to have. Briefly speaking, it keeps domain models (object that you work with) in the depth of your application.
Next, it wraps the core with application layer (where the logic, that relies on domain models, lays). Application layer only knows how to process underlying models.
And the last wrapper is (port) adapter layer. It adapts your logic for specific technology. It can be, for example, external API or wrapper for MongoDB (while application layer declares only an interface for collecting documents, this layer adapts (implements) it for concrete technology). It can also provide a marshalling/demarshalling.
Maybe example can explain it better:
Domain model is a document (an article) that your service works with.
Application layer knows how to process them (collect, order, filter articles), but knows nothing about JSON serialization.
Resource (aka port adapter) knows how to serialize collection of articles into JSON and back, but it's the only thing it does. No logic here
And you may have seen how every layer knows only about it's underlying layers. An article does not know anything, it's just a model. Application knows how to process articles. And adapter knows how to adapt processing results for concrete technology, JSON for instance.
So i would suggest you to provide basic validation (not against domain/application layer logic) and marshalling/demarshalling process at the highest level, at the resource (your #RestController's endpoints, for instance) since JSON is just a way to adapt your domain for external connections

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.

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