Why would I want to manualny create rest controllers for my REST server in Spring boot if ( as showcased in this short video: https://youtu.be/Of1IcjpGNNg) i only need a model and a CRUD repository to make the server work? It seems like Spring automaticaaly generates controllers for all crud methods that can be accessed with POST, GET etc.
Because you want to separate responsibilities as much as possible which makes oop like programming. It may be hard to understand when you have proper requirements rather than just basic CRUD operations. But when you have more business logic, more unit tests than it becomes harder to test, maintain and adapt the code. Just to strengthen your understanding, you can start with some basic rules like;
1) A class must have only 1 reason to change.
2) Unit tests should have minimum asserts and verifies
Then It starts makes sense. Think about the scenario, your requirements are changed now business says that they need weather forecast information with every request. So what you are gonna do, after retrieving data from DB, you will make a new Rest request in your same class? Now you have a new layer -> YourService. Even you can have WeatherService layer under the YourService layer. So the responsibilities;
Controller
Call the YourService, check the exceptions and return the response. It didn't change with new requirements
YourService
Call other services, retrieve and merge the response and return the merged data
WeatherService
Call weather API and return the data
So same with the tests. You need minimum assertions in your test;
ControllerTest
controllerMethod_validRequestParams_shouldCallProperServices
controller_whenServiceFails_shouldThrowDummyException
and so on. You can search more with those tags; SOLID principles, DRY, MVC, Clean Coding
Related
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));
I am looking at microservices, and the possibility of migrating some of our code to this architecture. I understand the general concept but am struggling to see how it would work for our example.
Supposing I have an interface called RatingEngine and an implementation called RatingEngineImpl, both running inside my monolithic application. The principle is simple - The RatingEngineImpl could run in a different machine, and be accessed by the monolithic application via (say) a REST API, serializing the DTOs with json over http. We even have an interface to help with this decoupling.
But how do I actually go about this? As far as I can see, I need to create a new implementation of the interface for the rump monolith (ie now the client), which takes calls to the interface methods, converts them into a REST call, and sends them over the network to the new 'rating engine service'. Then I also need to implement a new http server, with an endpoint for each interface method, which then deserializes the DTOs (method parameters) and routes the call to our original RatingEngineImpl, which sits inside the server. Then it serializes the response and sends it back to the client.
So that seems like an awful lot of plumbing code. It also adds maintenance overhead, since if you tweak a method in the interface you need to make changes in two more places.
Am I missing something? Is there some clever way we can automate this boilerplate code construction?
The Microservice pattern does not suggest you move every single service you have to it's own deployable. Only move self sustaining pieces of logic that will benefit from it's own release cycle. I.e. if your RatingEngine needs rating-logic updates weekly, but the rest of your system is pretty stable - it will likely benefit from beeing a service of it's own.
And yes - Microservices adds complexity, but not really boiler plate code of HTTP servers. There are a lot of frameworks around to deal with that. Vert.x is one good. Others are Spring Boot, Apache Camel etc. A complete microservice setup could look like this with Vert.x.
public class RatingService extends AbstractVerticle implements RatingEngine{
public void start() {
vertx.createHttpServer().requestHandler(req -> {
req.response()
.putHeader("content-type", "application/json")
.end(computeCurrentRating().encodePrettily());
}).listen(8080);
}
#Override
public int getRating(){
return 4; // or whatever.
}
protected JsonObject computeCurrentRating(){
return new JsonObject().put("rating", getRating());
}
}
Even the Java built-in framework JAX-RS helps making a microservice in not too many lines of code.
The really hard work with microservices is to add error-handling logic in the clients. Some common pitfalls
Microservice may go down If call to RatingService gives connection refused exception - can you deal with it? Can you estimate a "rating" in client to not prevent further processing? Can you reuse old responses to estimate the rating? .. Or at least - you need to signal the error to support staff.
Reactive app? How long can you wait for a response? A call to in memory methods will return within nano seconds, a call to an external HTTP service may take seconds or minutes depending on a number of factors. As long as the application is "reactive" and can continue to work without a "Rating" - and present the rating for the user once it's available - it's fine. If you are waiting for a blocking call to rating service, more than a few millisec. - response time becomes an obstacle. It's not as convenient/common to make reactive apps in Java as in node.js. A reactive approach will likely trigger a remake of you entire system.
Tolerant client Unit/integration testing a single project is easy. Testing a complex net of microservices is not. The best thing you can do about it is to make your client call less picky. Schema validations etc. are actually bad things. In XML use single XPaths to get data you want from the response, not more not less. That way, a change in the microservice response will not require updates of all clients. JSON is a bit easier to deal with than XML in this aspect.
No, unfortunately you do not miss anything substantial. The microservice architecture comes with its own cost. The one that caught your eye (boilerplate code) is one well-known item from the list. This is a very good article from Martin Fowler explaining the various advantages and disadvantages of the idea. It includes topics like:
added complexity
increased operational maintance cost
struggle to keep consistency (while allowing special cases to be treated in exceptional ways)
... and many more.
There are some frameworks out there to reduce such a boilerplate code. I use Spring Boot in a current project (though not for microservices). If you already have Spring based projects, then it really simplifies the development of microservices (or any other not-Microservice-application based on Spring). Checkout some of the examples: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples
currently I'm learning the SpringMVC + Hibernate. And I'm confused while implementing a simple user account manager application.
In my case:
the user account should be read from the database;
the password should be compared before any modification;
the user account information should be modified according to the frontend form;
the user account with new information should be save back to the database;
My questions are:
Should this whole process be implemented in the Service or in the Controller? And why?
In many examples I read that the service methods are usually tiny and contains only one DAO call, is this a good practice? Or we do the contrast to put several DAO calls into one service methods?
Should this whole process be implemented in the Service or in the Controller? And why?
Business logic is done in the service layer (the M in MVC) - see the link below for explanations.
In many examples I read that the service methods are usually tiny and contains only one DAO call, is this a good practice? Or we do the contrast to put several DAO calls into one service methods?
Service methods are of the proper size for the logic they perform. If for a particular logic you need access to several DAOs, or other services for that fact, you do so. If the logic is 10 lines of code or 100 then that's the size of the method. The thing is that most examples out there use a service layer (which your application should have) but because they are just that, examples, there isn't any logic in them. For this reason most of them just delegate to some DAO, confusing people about what their purpose should be.
Read the following for details: The Purpose of a Service Layer and ASP.NET MVC 2 (it's for .NET but the principles still apply).
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 been doing Java and Ruby (and used frameworks) for some while and I know MVC is a way to separate code. The thing is, I think I never really used it in the way it should.
The first question is: Business logic, what does it mean? Does Business logic mean the logic that is special for that application? Let say you are building a Satellite system. Is the business logic the code that is unique for that Satellite system and make it work?
What does "domain" mean? Like in domain logic or domain as a term.
"Keep your model smart, controllers thin and view dumb". This statement clearly indicates that the controllers which I load with too much code is the wrong way of writing it.
As an example. If you have a BankAccount class. Then should this class provide methods for behavior such as validating etc as well as getter/setter?
What should the controller be doing? Just redirecting input/events in the view to the model and maybe update view (which is the case in webframeworks).
For example in Java and JPA you have the entityManager that you use for finding entities, maybe do something on them etc. Should this entitymanager be used in the controller, or should you make another layer named e.g. "Service" which the controller uses. But again, does this server layer then belong to the Model in MVC? How would you do this in Rails?
I don't get the Model nor the Controller concept right I think.
Think of applications as being layered. When working on each layer, always think to yourself, "Is this layer dependent on the layer above it or can it work independently?" That is the basis to a good MVC application.
When thinking of layers in an MVC style application, there are a few.
In my mind the layers (from top to bottom) are the view, controllers, business logic, and data access.
The view could be JSP or even AJAX requests from jQuery. This is where the user interacts with your application. The view sends information to the business logic layer to do work.
Controllers should be written to collect data sent to it from the view, transform it in a way that the business logic can understand it, and then pass the information into the business logic layer. Controllers may also take information retured from the business logic layer, transform it, and send it back to the view. No real "business logic" should happen here. Think of it as a broker between the view and the business object layer. This is also a great spot for validating data submitted by the view.
Business logic is a layer you would find in the middle, typically between the controllers and data access layer. This could also be called a service layer. It should be written to not know anything about what is calling it. If written correctly, you could use this layer in a standalone application. Here is where a lot of the application smarts should take place. A lot of times, this layer is simply here to call the data access layer and return the results back to the controllers. But, a lot of other things could go on here like data manipulation, calculations, data security, validation, etc.
The data access layer should be written in such a way that it takes it's input, retrieves the appropriate data, transforms it into a useable form, and returns it. This layer should not know or care what is calling it and should be written in that way. Again, this layer should not know it is in a web application or a stand alone application. There are a lot of options here to make your life simpler in the form or ORM (Object Relational Mapping) frameworks. If your application is a step above trivial, you should think about using one.
In the traditional sense, the model could be the business logic layer and the data access layer as well as the domain objects that go along with them.
Using "BankAccount" as an example:
"BankAccount" sounds more like a domain object (representation of data in a database) than a class that has logic in it. Typically domain objects only have the fields they need (account number, balance, etc.) with getters and setters.
The user might log into their bank website. On login, the view sends the username to the controller (BankAccountController). The controller takes this information out of the request and sends it to the service layer (BankAccountService). The service layer would send this information to the data access layer which does a query for the BankAccounts that the user might have and return them to the service layer which returns them to the controller. The controller will manipulate this information in some way that the view layer can display them to the user. There would be a similar series of events when the user transfers money between accounts, for instance.
Hope this helps... let me know if you have any more questions or if something isn't clear.
Edit:
Besides the links posted by the other users, Wikipedia has a brief, but pretty good article on MVC.
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller