I am developing a spring application, where I have three layers as most of other spring apps. The Rest Controllers on front, Services in middle, and JPA repositories in behind. Now we have spring entities mapped to the db, in my case they are plain old java objects(POJO), with only some fields and getters and setters which I usually prefer and don't want to put any business logic in there. However, in this project, I find out that in a lot of services I am repeating the same piece of code, something like that
User user=userRepository.findUserByName("some name here");
if(user==null){
throw new UserNotFoundException("User not found");
}
Now, this is not only for a single entity, there are many other similar repeated parts too. So, I have started to worry about it and looking possible areas to push that code and eliminate the repeated parts. One thing makes sens as stated in domain driven design, put that business logic inside the entity, now they will have both data and part of business logic. Is that a common practice?
Pretty much looks like a simple code reuse problem. If you are always throwing the same exception in all contexts then what about implementing a findExistingUserByName method on the repository that throws if the user doesn't exist?
Your code would become:
User user = userRepository.findExistingUserByName("username");
If you do not want to change the repository contract you could also implement a UserFinderService at the application level which wraps over a UserRepository and provides that service-level behavior.
Another more generic idea could be to implement a generic method and make it available to your application services either by inheritance, composition or a static class which would allow you to do something like:
withExistingAggregate<User>(userRepository.findUserByName("username"), (User user) -> ...)
You cat return Optional<User> from repository in this and similar cases.
Then you service code will look like:
userRepository.findUserByName("some name here")
.ifPresent(user -> doThmsWithUser(user));
Related
We are a small team starting a new project, and developing the back-end using Spring-Boot framework.
The back-end project will have the following standard layers of a Spring-Boot application:
Controller (map the endpoints and handle)
Service (to handle business logic)
Repository (to abstract and interact with the database)
We also have an entity package where all the classes representing database entities are located.
We also use a library to map entities with Api models.
It did not last long and our first debate within the team occurred. So I thought it's a good idea to ask for advice out there.
My other partners think that the controllers should contain as few lines of code as possible.
Ideally containing only one line of code, where the respective Service is called, and the rest is handled in the Service.
I am against that approach, because if we would do that, the Service and the Controller would end up having the same interface, which feels wrong.
However, I agree with the principle that the controllers should have as few lines of code as possible.
I think that the controllers methods should accept and return only Api models, and no concept of entities should be present in the controllers.
At the same time, I think that the services method should accept and return entities, and not work with ApiModels.
Should we introduce a new layer between Controller and Service? Is there some standard, for which I am not aware, related to this topic?
I am going to give you a concrete example with two approaches (mine and my partners'):
First approach:
public class UserController implements UsersApi {
#Autowired
private UserService userService;
#Override
public ResponseEntity<UserAPIModel> createUser(#Valid UserAPIModel body) {
User createdUser = userService.save(UserMapper.INSTANCE.toUserEntity(body));
return ResponseEntity.ok(UserMapper.INSTANCE.toUserAPIModel(createdUser));
}
}
And the service:
public class UserService {
#Autowired
private UserRepository repository;
public User save(User entity) {
return repository.save(entity);
}
}
The second approach:
public class UserController implements UsersApi {
#Autowired
private UserService userService;
#Override
public ResponseEntity<UserAPIModel> createUser(#Valid UserAPIModel body) {
return ResponseEntity.ok(userService.createUser(body));
}
}
and the service:
public class UserService {
#Autowired
private UserRepository repository;
public UserAPIModel createUser(UserAPIModel body) {
User user = repository.save(UserMapper.INSTANCE.toUserEntity(body));
return UserMapper.INSTANCE.toUserAPIModel(user);
}
}
As you can see in the first approach, the mapping from entity to Api Model and vice versa is done in the Controller. In the second approach this mapping is done in the Service.
Which one would you recommend? Or do you think it's better to introduce a new layer between Controller and Service?
Making a decision on this simple example, can help us to create a more general rule and set a standard for similar problems in the future.
First of all, your question is very broad, which incorporates many questions in one post, which you should not be doing on this site. In the future, try to have more focused questions instead.
TL;DR:
#Controller is a Web-Layer, i.e. layer responsible to handle HTTP Request-Response responsibility, where your Java code should semantically talk web, i.e. responsibility of your controller should be to accept the HTTP Request, and respond with HTTP Response. Whether or not you do some logic in between, should not be much a pure responsibility of controller, it should stand on the shoulders of its dependencies (#Service, in most cases).
#Service is a Business-Layer, i.e. layer responsible to process business-related tasks, where all the major business-logic, transactions, file processing, batch processing or etc. may be taking place.
You can mix-and-match these two, but it's not a good idea. Rather follow a clear separation of concerns pattern, where #Controller will be responsible for web layer, and #Service - for business logic.
Your points:
My other partners think that the controllers should contain as few lines of code as possible
Not necessarily, it depends. Controller might do some work, depending what is the given circumstance and there is no controller-specific Clean Code practice. Clean Code instructs you, that generally, your methods should not be too long and messy (there is a funny rule, that no method should go longer than a height of your 5 fingers, when laid horizontally), but again, this is very generic and debatable rule;
Ideally containing only one line of code
Do not follow this as a rule. This is rarely real, unless your controller does nothing except calling some service API (like return findAll(););
where the respective Service is called, and the rest is handled in the Service
You partner is right, if he/she means, that business-related (that is transactional, DB accessor, Batch, or any other type of process, that is OUT OF the web-layer responsibility) should better be handled in a Service layer;
#Service components are oriented to be acting as
Business Service Facade;
I am against that approach, because if we would do that, the Service and the Controller would end up having the same interface, which feels wrong.
No, they will not. #Controller does not need any Java Interface, in the classical sense of this phrase (e.g. public interface Foo{..}), it's a Spring managed component, and you don't inject its implementations, which is not the case when we're talking about #Service components;
However, I agree with the principle that the controllers should have as few lines of code as possible.
Don't conceptualize this on controller. Method, generally, should be as clear as possible, and there is nothing wrong if controller is a bit long.. it's not about controller, as such, it's about your methods' design, whether or not you can extract/abstract something out and make your code cleaner. However, apply YAGNI principle when possible and don't rush with premature optimization with respect of the controller's code lines. Don't go too long.. but don't bother yourself much here on counting lines;
I think that the controllers methods should accept and return only API models, and no concept of entities should be present in the controllers.
Wrong. #Controller's responsibility is not directly bound to the API model, it's responsibility is to accept HTTP Message, do something with it (either with the help of #Service, UtilityClass, or etc.) and respond back with HTTP Response. In some cases, you can make your controller be dependent on Data Access layer directly, but again - it depends.
Whether you'll have accepting models or not, it also very much depends and you can see my other answer explaining whether you should use DTO or not;
Should we introduce a new layer between Controller and Service?
NO, unless it's necessary. Controller should be the first layer where your request ends up; it should usually rely on Service, and Service, eventually, will rely on Data Persistence layer (Spring Data, JDBC, Integrations, or any other thing).
Ho guys!
I too started working on Springboot a few months ago, I can tell you that from personal experience it is better to create a Mapper between Controller and Service in order to proceed better. Generally, especially in this type of projects, it is imperative to diversify and not to make the Controller or the Service do tasks outside of their use. The controller in this case you only need to start a command, there shouldn't be any kind of direct connections to Repo either. from experience I tell you that in larger projects this mentality pays off
I have a web service layer that is written in Java/Jersey, and it serves JSON.
For the front-end of the application, I want to use Rails.
How should I go about building my models?
Should I do something like this?
response = api_client.get_user(123)
User user = User.new(response)
What is the best approach to mapping the JSON to the Ruby object?
What options do I have? Since this is a critical part, I want to know my options, because performance is a factor. This, along with mapping JSON to a Ruby object and going from Ruby object => JSON, is a common occurance in the application.
Would I still be able to make use of validations? Or wouldn't it make sense since I would have validation duplicated on the front-end and the service layer?
Models in Rails do not have to do database operation, they are just normal classes. Normally they are imbued with ActiveRecord magic when you subclass them from ActiveRecord::Base.
You can use a gem such as Virtus that will give you models with attributes. And for validations you can go with Vanguard. If you want something close to ActiveRecord but without the database and are running Rails 3+ you can also include ActiveModel into your model to get attributes and validations as well as have them working in forms. See Yehuda Katz's post for details on that.
In your case it will depend on the data you will consume. If all the datasources have the same basic format for example you could create your own base class to keep all the logic that you want to share across the individual classes (inheritance).
If you have a few different types of data coming in you could create modules to encapsulate behavior for the different types and include the models you need in the appropriate classes (composition).
Generally though you probably want to end up with one class per resource in the remote API that maps 1-to-1 with whatever domain logic you have. You can do this in many different ways, but following the method naming used by ActiveRecord might be a good idea, both since you learn ActiveRecord while building your class structure and it will help other Rails developers later if your API looks and works like ActiveRecords.
Think about it in terms of what you want to be able to do to an object (this is where TDD comes in). You want to be able to fetch a collection Model.all, a specific element Model.find(identifier), push a changed element to the remote service updated_model.save and so on.
What the actual logic on the inside of these methods will have to be will depend on the remote service. But you will probably want each model class to hold a url to it's resource endpoint and you will defiantly want to keep the logic in your models. So instead of:
response = api_client.get_user(123)
User user = User.new(response)
you will do
class User
...
def find id
#api_client.get_user(id)
end
...
end
User.find(123)
or more probably
class ApiClient
...
protected
def self.uri resource_uri
#uri = resource_uri
end
def get id
# basically whatever code you envisioned for api_client.get_user
end
...
end
class User < ApiClient
uri 'http://path.to.remote/resource.json'
...
def find id
get(id)
end
...
end
User.find(123)
Basic principles: Collect all the shared logic in a class (ApiClient). Subclass that on a per resource basis (User). Keep all the logic in your models, no other part of your system should have to know if it's a DB backed app or if you are using an external REST API. Best of all is if you can keep the integration logic completely in the base class. That way you have only one place to update if the external datasource changes.
As for going the other way, Rails have several good methods to convert objects to JSON. From the to_json method to using a gem such as RABL to have actual views for your JSON objects.
You can get validations by using part of the ActiveRecord modules. As of Rails 4 this is a module called ActiveModel, but you can do it in Rails 3 and there are several tutorials for it online, not least of all a RailsCast.
Performance will not be a problem except what you can incur when calling a remote service, if the network is slow you will be to. Some of that could probably be helped with caching (see another answer by me for details) but that is also dependent on the data you are using.
Hope that put you on the right track. And if you want a more thorough grounding in how to design these kind of structures you should pick up a book on the subject, for example Practical Object-Oriented Design in Ruby: An Agile Primer by Sandi Metz.
Background:
I have a design pattern problem that I was hoping someone may be able to solve. I program in PHP but I believe DAO/VO is popular in Java.
I have been using MVC for many years now. I designed a shopping that was MVC but used procedural programming. Thus recently I decided to develop the cart again, using OO.
Problem:
The problem I was faced with was that my Product class did not make sense to have a RetrieveAll() method.
E.g. If I had 10 products listed, from which instance would I call the RetrieveAll() method? I would have 10 choices.
Solution:
Thus, I found the DAO/VO pattern.
Unless I have not researched this pattern enough - I believe that each DB table must have a Model + DAO. No model or DAO should know about another set of models or DAO's. Thus being encapsulated.
The pattern makes perfect sense, pulling the database layer away from the Model.
However. In the shopping cart, my products are assigned categories.
A category could be electronics, clothing, etc.
There are 3 tables:
- Category (pid, name)
- Category Item (iid, name)
- Category Link (pid, iid)
From an MVC approach, it doesn't make sense of which DAO the controller should be talking to?
Should it be:
The controller talks to all 3 DAO's and then return the appropriate data structure to the View?
Or should the DAO's talk to one-another (somehow) and return a single structure back to the Controller?
Please see here for example (image)
I'm not sure what do you mean by VO. Is it value object?
I'm a huge fan of the DDD (domain driven design) approach (though I don't consider my self as guru in it). In DDD you have so called Services. Service Is an action that operates on your domain and returns data. Service encapsulates the manipulation with you Domain data.
Instead of having the controller to do all the domain logic like what items to retrieve, what DAO's to use and etc (why controller should care about the Domain anyway?), it should be encapsulated inside the Domain it self, in DDD case inside a Service.
So for example you want to retrieve all the Category items of the category "electronics".
You could write a controller that looks like this (forgive me if the code have invalid syntax, its for the sake of example):
public function showItemsByCategoryAction($categoryName) {
$categoryId = $categoryDAO->findByName($categoryName);
if(is_null($categoryId)) {
//#TODO error
}
$itemIds = $categoryLinkDAO->getItemsByCategoryId($categoryId);
if(empty($itemIds)) {
//#TODO show error to the user
}
$items = $categoryItemDAO->findManyItems($itemIds);
//#TODO parse, assign to view etc
}
This introduces at least two problems:
The controller is FSUC (Fat stupid ugly controller)
The code is not reusable. If you would like to add another presentation layer (like API for developers, mobile version of the website or etc), you would have to copy-paste the same code (expect the part of the view rendering), and eventually you will come to something that will encapsulate this code, and this is what Services are for.
With the Services layer the same controller could look like
public function showItemsByCategoryAction($categoryName) {
$service = new Item_CategoryName_Finder_Service();
$items = $service->find($categoryName);
if(empty($items)){
//#TODO show empty page result, redirect or whatever
}
$this->getView()->bind('items', $items);
}
The controller is now clean, small, and all the Domain logic is encapsulated inside a service that can be reused anywhere in the code.
Now some people believe that the controller should know nothing about DAOs and communicate with the Domain only by using Services, other says that its ok to make calls to DAOs from the controller, there are no strict rules, decide what suits better for you.
I hope this helps you!
Good luck :)
I'm not an expert in DDD either , but this is my opinion. This is the situation where the repository patern is applied. Basically, the Domain doesn't know nor care about DAO or anything else rpesistence related. At most knows about the repository inteface (which should be implemented at the infrastructure level).
The controller knows about the domain and the repository. The repository encapsulates everything db related, the application knows only about the repository itself (in fact the interface as the actual implementation should be injected). Then within the repository you have DAOs however you see fit. The repository receives and sends back only application/domain objects, nothing related to db acess implementation.
In a nutshell, anything db related is part and it's an implementation detail of the repository.
return type can be considered when deciding which dao method should go to which dao class, hence which dao should the controller talk to:
Implement one DAO class per Data Entity is more cleaner,
CRUD operations should go in to Dao classes,
C-Create, R-Read, U-Update, D-Delete
Read operations are not like Create, Update, Delete, most of the time Read operations have different flavors when considering what they return.
for Read operations, return type can be considered when deciding which dao method should go to which dao class
following are some Business Entities and there Dao
Exchange -> ExchangeDao
Company -> CompanyDao
Stock -> StockDao
I have the following situation:
Three concrete service classes implement a service interface: one is for persistence, the other deals with notifications, the third deals with adding points to specific actions (gamification). The interface has roughly the following structure:
public interface IPhotoService {
void upload();
Photo get(Long id);
void like(Long id);
//etc...
}
I did not want to mix the three types of logic into one service (or even worse, in the controller class) because I want to be able to change them (or shut them) without any problems. The problem comes when I have to inject a concrete service into the controller to use. Usually, I create a fourth class, named roughly ApplicationNamePhotoService, which implements the same interface, and works as a wrapper (mediator) between the other three services, which gets input from the controller, and calls each service correspondingly. It is a working approach, though one, which creates a lot of boilerplate code.
Is this the right approach? Currently, I am not aware of a better one, although I will highly appreciate to know if it is possible to declare the execution sequence declaratively (in the context) and to inject the controller with and on-the fly generated wrapper instance.
Also, it would be nice to cache some stuff between the three services. For example, all are using DAOs, i.e. making sometimes the same calls to the DB over and over again. If all the logic were into one place that could have been avoided, but now... I know that it is possible to enable some request or session based caching. Can you suggest me some example code? BTW, I am using Hibernate for the persistence part. Is there already some caching provided (probably, if they reside in the same transaction or something - with that one I am totally lost)
The service layer should consist of classes with methods that are units of work with actions that belong in the same transaction. It sounds like you are mixing service classes when they could be in the same class and method. You can inject service classes into one another when required too, rather than create another "mediator".
It is perfectly acceptable to "mix the three types of logic", in fact it is preferable if they form an expected use case/unit of work
Cache-ing I would look to use eh cache which is, I believe, well integrated with hibernate.
In another question, someone told me to implement the following in my java program. But, I am very new to Java and I do not know how to start to convert my simple program into this structure:
Data Access Layer (read/write data)
Service Layer (isolated business logic)
Controller (Link between view and model)
Presentation (UI)
dependency injection.
program to the interface:
Does that come inside some framework? Should I start learning Spring and this structure will evolve naturally? Or, can I implement above technologies one by one without using a framework?
You can implement them without a framework if you wish, but you give up whatever benefits the framework offers you.
The layering you cite is correct and independent of any framework; it's just programming to interfaces and separation of concerns. You're free to do it without Spring if you wish to minimize the number of new technologies you want to learn right now.
If you don't know what persistence is, then you shouldn't jump into Spring. Persistence means storing data in relational databases using SQL to most people. If you don't know that, I'd recommend starting there.
All the patterns books in the world won't help you if you've never used the underlying technologies.
If you've never done any of this, I'd recommend sticking to straight JDBC, servlets, and JSPs using only JSTL (no scriptlets). Anything beyond that will just be confusing.
If you had a Foo model object, with persistence, service, and view tiers, the interfaces might look like this:
package model;
/**
* A model object that's interesting from your problem's point of view
*/
public class Foo
{
}
package persistence;
/**
* CRUD operations for a Foo
*/
public interface FooDao
{
Foo find(Long id);
List<Foo> find();
void saveOrUpdate(Foo foo);
void delete(Foo foo);
}
package service;
/**
* Just a data service that wraps FooDao for now, but other use cases would
* mean other methods. The service would also own the data connection and manage
* transactions.
*/
public interface FooService
{
Foo find(Long id);
List<Foo> find();
void saveOrUpdate(Foo foo);
void delete(Foo foo);
}
package view;
/**
* A class that owns services, validates and binds input from UI, and handles routing
* to the next view once service is complete.
*/
public interface FooController
{
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response);
}
These are just interfaces, of course. You'll need to provide implementations.
You might want to check out Domain Driven Design. The Code samples are in Java. The things you listed are design related more than any specific technology.
In short:
Data Access Layer is a module of your application that provides interface to your data. Data may be in SQL database, XML, file wherever. You write interfaces and classes that provide interface to access data usually as VO or DTO via DAOs
Service Layer contains most of the use-case logic. Service layer interacts with Data Access Layer to perform tasks in given use case. I did not find a good article on introductory service layer. You may see here and there
Controller is the one that interacts with Service Layer and/or Data Access Layer and/or other controllers in order to perform a specified client's tasks. For example, a sign-off button controller will request a sign-off action/service to invalidate user's sessions on all services that user is logged on to, then it will choose an appropriate view or log-off web-page to forward user to.
Presentation is your user interface. It can be a web-page made of HTML or Java Swing window or anything that user interacts with. GUI commonly known term for it. This is what your users will be interacting with using mouse clicks, scrolls, swipes, drag-and-drop. These actions are mapped with controller which performs action based on what user performed on UI.
Dependency Injection is a way to wire various components. There are a lot of resources on web. You can look in Martin Fowler's this article. It's basically a mechanism that allows components to behave much like plug-and-play devices, if you know what plug goes where.Spring is a good implementation of dependency injection. You may not want to write your own framework, and at this stage, you should rather not. There is a Spring MVC framework that can do things for you.
But I suggest you start from very basic. Instead of jumping on jargon, read from basic. Start with a good book on application development using Java. You can also look into
Design Patterns - Gang of Four
Core J2EE Patterns
Developing a Spring Framework MVC application step-by-step
dependency Injection with the Spring Framework
You can implement all of this is you want -- it's been done many times before, but nothing prevents you from doing it again.
What would be a better use of your time is to make sure you understand the separation of concerns you listed above (which are generally right) and identify the most efficient integration of existing frameworks to leverage (e.g., Hiberante, Spring, Guice, etc). There are multiple answers for that one (and no shortage of opinions!), but all things being equal, the less frameworks you have to integrate, the easier and better fitting it's likely to be.
Spring has a very well known framework which covers many of these things, so it would be wise to start there. It also allows you to work with other frameworks (i.e., you can use selective parts of Spring). For example, you can use Spring for dependency injection and use a different MVC framework.
It is very hard to answer this question. First of all, I don't know what your program looks like. Second, I don't think 'converting' it is something that can be done, or should be done for that matter. What you're talking about are architectural concepts that the developers usually have in mind while designign the application.
If these concepts interest you, I suggest reading a bit about Model-View-Controller pattern (MVC) and service-oriented Architecture (SOA).
These are general concepts that do not apply specifically to Java. However, they are widely used in Java enterprise development. Various frameworks allow you to create applications utilizing these concepts. For example, Spring Web MVC, as others have pointed out, is part of the Spring Framework that lets you create web applications that adhere to the MVC pattern.
If your program is really simple this separation might be done by using one calss for each
category.
Data Access Layer (read/write data) -> one class for presisting laoding
Service Layer (isolated business logic) -> one calss with bussiness logic
Controller (Link between view and model) -> in simple swing app this merges with UI
Presentation (UI) -> one class for one widnow
dependency injection -> not used in small apps
program to the interface -> Your service class should use interface tah is used by other class instead of directly your serivce implementation:
if it's not as simple program you might want to have package for each category.
BUT - don't overdesign! These concepts are ment to help you manage large scale applications, not to ruin you in your programming begginigs!