Merge REST Controllers with Services in Spring - java

When we use Controllers in spring framework to provide rest services to client or frontend for example in JSON format we mainly separate our java logic into two layers: Controllers and Services. But what I found by now is that Controllers stay almost entirely empty of implementation and simply delegate to the service layer.
After some experience I started thinking that Controllers as they are thought to be one of the layers in MVC spring framework have different meaning when you use them to provide simple REST services without building presentation layer and you can use them as pure service layer. Something more - if you remove all the spring annotations like #Component, #RequestBody, etc. this classes become pure services and there is no need to keep separation between controllers and services. Even if you speak about them you usually say something like this: We provide REST SERVICES to the client"
Is there something big that I am missing?
But please keep in mind the real world and don't say something like:
"If aliens come down to earth the code might brake."

You are right controller is extra layer in Spring MVC architecture but it is important to make your code manageable. The sole purpose of controller is to map your HTTP request, get request data and call service to process those data and provide response data.
On the other hand, Service layer is re-usable type of layer in MVC architecture. services are made up of method which can be reused when required and if you don't use services and do your business logic in controller only it is more complex to manage and won't be readable code.
Moreover, annotation like #Service, #Repository, and #Controller is just for identification you can also use #Component annotation instead of these. But annotating properly will make code more readable and understandable of it's purpose. Hope I answered your question.

Related

What's the preferred way to handle Spring Security for JMS Listeners?

I have a somewhat monolithic Java application, built around Spring #Service beans for my business service layer. As a rule, each of my business service methods has Spring Security annotations (e.g. #PreAuthorize) to enforce appropriate authorization rules for that action.
Within the main web application flow, this works very well; each web request implicitly has authentication handled by session cookies, etc.
However, when it comes to various integration points with other, "internal" systems, I'm not seeing as clear of a solution.
For example, I am going to be consuming methods from a JMS queue, which already has its own authentication & authorization rules defined within the broker, so I want to implicitly "trust" the messages that I get. However, as things stand now, a simple enough Camel route like this:
WidgetService widgetService = lookup(WidgetService.class);
from("activemq:newWidget")
.unmarshall(...)
.bean(widgetService, "newWidget");
ends up throwing a AuthenticationCredentialsNotFoundException.
This tells me that Camel is calling my bean correctly, with all of the magic AOP applied from Spring.
With other things of this sort, I've resorted to applying AOP advice around the entry point for the system (e.g. around a Quartz Job's execute method), which injects a PreAuthenticatedAuthenticationToken, but I'm not sure if that's really the best approach.
Should I continue to wrap these "trusted" entry points in advice to add an Authenication context, or should I change my service layer to have special forms of some business methods which require no authentication, and just make sure I document clearly that they are not for use in web #Controller methods, etc?
Unfortunately there is best way to do that. It depends on the application and in my experience all solutions work but have some drawbacks.
The first solution would be to move the #PreAuthorize up to the web level. This way you will be free to use your services internally as much as you want. I think this is the simpler solution and easier to comprehend. You want to secure your web users right? Why not apply the security to in the web layer. The problem with it is that web layer changes more often than the business layer and it is easier to leave security breach if you don't develop your controllers and endpoints carefully. I would still take that approach for most applications and let the service layer take care just of business rules and not security (which is kind of business rule too? ). Of course you can still add some default security logic to groups of controllers and stuff so you don't have to repeat yourself everywhere.
The second approach is the one that you have taken. Run such methods in authenticated context which you generate. And it is a bit counter-logic - why to run in authenticated context when there is no authenticated user? You shouldn't have to do it but unfortunately that's the only way if you want to have secured services. This methods is less prone to security errors and you can maintain the security easier. If you stick to that you can use the template pattern or create some executor class that runs stuff in context.
I cannot think of a third approach :)

Best practice to have a RestController and a Controller in Spring Application

I am not asking if it is possible, I know it is but I would like to know what's the best way to offer a rest service while having a front end in my application.
I'm developing a Spring Boot application, I currently have a controller that calls jsp pages, and a separate RestController. I want to be able to consume it with an Android application.
So is it correct to have both a Controller and a separate Restcontroller in my application? For example the Rest controller methods will be called from /api/*.
Edit :
I know the difference between the two, but since I want to be able to return a view ( and I shouldn't do that with a RestController) and I want to have a rest service I am wondering if I can have both of them (separately of course).
Thank you so much in advance.
I'd say that it's possible, but considered a bad practice (except for corner cases like a controller for Swagger in a REST application) in a typical, layered, spring app (will get back to that)
you may want to create a multi-module project, that may look like that:
parent project
-- core
-- web api (jsp based)
-- rest api (for android)
both web api and rest api depend on the core.
web api and rest api are separate deployment units. you can deploy them on the same server or run as separate applications (for example using spring boot). Depends on your usecase.
with that you can have your business logic in one place (core).
you may also want to read about ports and adapters architecture, which may give you an idea how to solve this in a more organized way than just having Controllers and RestControllers sitting side by side

Understanding event-driven in a Spring MVC application

I've read the code from this Spring MVC application:
https://github.com/spring-guides/tut-rest/tree/master/6/complete/src/main/java/com/yummynoodlebar/core/events
I don't understand the role of those classes from events folder. How can
I catch such a event in another place in application?
Another thing which I don't understand at this application, is why
they doesn't use command-query separation somewhere at service layer. They
used CQS on their rest controllers. I'm not agree with that, instead, they
should use CQS on service-layer to provide a easy way to add validation
or other core operations to their services. This link describes what I'm
talking about CQS separation on service layer.
If you have suggestions about how to implement the CQS pattern described in
the link from above, please tell it.

spring mvc dao and service bean mapping

I am new to Spring and hibernate.
I am trying to learn the best practices and design methodoligies in j2ee apps.
I have a managed to create a basic spring mvc web app. now lookin for that
- how should i map my service beans to dao beans or should just use dao beans only.
- Is there any need to make DAO classes singleton
- If i use same dao bean for the jsp, then e.g. onSubmit if I have to enter data on multiple tables (dao beans) then how would I do that.
1 service bean to more than 1 dao beans??
and any refrence material on designing good web app using spring hibernate would appreciated ;)
thanks
You must use service bean. service logic should be there only.
DAO should only for DB related operation.
Now you can inject multiple DAO in your service bean.
FWIW - I just went through a similar learning process on Spring. The good news is, there are a lot of examples out on google; the bad news is, there are not a lot of "complete" examples that are good for rookies (also if you are going to target v3 Spring, there is a lot of pre-v3 stuff out there that can be confusing based on the new baseline). What worked for me was the following: started with the sample applications on the SpringSource site (http://www.springsource.org/documentation). Between their handful of examples, there are just about all the pieces you will need, at least in minimal form. When I found something in those examples that I needed, I googled based on similar terms (some of the # annotations etc) to find more complete information/better examples on that given topic. Many of those searches led me back to this site, which is why I started frequenting here - lots of good questions already answered. I guess this isn't an overly insightful answer, but this process got me up and working through the basics in a fairly quick amount of time.
DAO layer and service layer are different entities:
DAO is responsible for getting and putting single objects from\to DB. For example, get User(id, name, lastname) from DB.
Service layer is responsible for your business logic. It can use several DAO objects for making one action. For example, send message from one user to another and save it in sent folder of first user and in inbox of recipient.
A service is about presenting a facade to the user that exposes business functions that the user can take. Basically, if you have a set of low-level use cases, the methods on the service would line up with individual user actions. Services are transactional, generally if the user does something we want all the consequences of that action to be committed together. The separation between controller and service means we have one place to put webapp-specific functionality, like getting request parameters, doing validation, and choosing where to forward or redirect to, and a separate place to put the business logic, stuff that doesn't depend on webapp apis and is about what objects get updated with what values and get persisted using which data access objects.
I see a lot of cases where people seem to think they need one service for each dao. I think their assumption is that because Data Access Objects and Controllers and Models are fairly mechanical about how they're defined, services must be the same way, and they construct them with no regard for the use cases that are being implemented. What happens is, in addition to having a lot of useless service boilerplate code, all the business logic ends up in the controller jumbled up with the web-specific code, and the controllers become big and unmanageable. If your application is very simple you can get by with this for a while, but it is disorganized, it's hard to test, and it's generally a bad idea. Separation of concerns, keeping infrastructure code in one place and business code in another, is what we should be aiming for, and using services properly is very helpful in getting there.

Should I duplicate validation in my MVC layer and Service layer?

I'm feeling a little conflicted at the moment. I have a web application using Stripes for an MVC framework and Spring/Hibernate for the back-end. I have an account registration method in my MVC layer which requires the following validation:
Username is not already taken
The provided email address is not already associated with another account
I have a validation method in Stripes (MVC layer) that checks these two cases but was wondering whether my service layer should duplicate these checks? If the service layer interface was exposed as a web service then I think the validation would be a good idea, but if it's only used in the context of a web application is it required?
Edit: I'm not intending to duplicate the validation code - I mean duplicating the validation method calls in two places.
I see my options as:
Duplicate the validation calls in both MVC and service layer
Only perform this validation in the MVC layer
Only perform this validation in the service layer.
What's best practice here? I'm looking for advice/opinions on which option I should go with and why.
Note that there are simple validation checks on the input fields of the registration form (like checking for blanks) and that I think these should be handled by the MVC validation only; I'm only concerned about more complex validations.
Don't duplicate code. Use JSR303 Bean Validation so you can use the same validation logic in all layers of your app.
Hibernate Validator (a separate project from the Hibernate ORM stuff) provides the reference implementation of this interface. It is dead simple to use, you can get started with it very quickly.
In my opinion you should diferenciate two kinds of validations:
The Format data validation: Which should be validated in the presentation layer (MVC in your case). Normally both in the client and the server side
The Bussines data validation: Which should be validated in the service layer
In your case your validations are related to business rules, so I will put them only in the service layer.
In addition, if you duplicate your validations in both layers you will be making the same queries twice, slowing down the performance of your application.
Annie,
Good question, I have asked myself the same in many occasions. Here's what I ended up with (until now).
The purest (but tedious) approach is to invoke the validation logic in both layers.
the pragmatic approach could be to only invoke it in web-land (e.g. your controllers).
I think there is no answer that ends all discussion. I think that it depends on the context of your project. If the project-size is modest (in terms of people and size of codebase) and you are confident that not a whole lot of code will be developed by others that invoke your service API (to an extent that you will not be able to oversee), then doing the validation in the web-layer only may well suffice.
However, if you expect many clients you may need a higher-level security. When I say security here, I refer to it as the level of consistency-guarantees that you need.
If that level is high, there is no way around it: you will have to do it in both the service (for security) and the web layer (mostly to be able to provide end-users with an acceptable experience).
So the key driver here is security and how much of it you really need. If you need a lot, you go for the 'purist' approach. If your application doesn't exactly make decisions that concern matters of life and death, you go for the pragmatic approach.
Ideally, do the validation in both layers, since your service layer may be used with a client other than the current mvc layer
Reuse the validation mechanism at both places (Bean validation, for example)

Categories

Resources