Spring Boot Best approach for validation in facade - spring-boot

I use Spring Boot with Kotlin and my project is splitted on modules where I have application layer with REST controllers and facades, domain layer with services and business logic and infrastructures layer for communication with external services or DBs. I think (but I can be wrong) that the best place for basic validation like notNull, notEmpty, max and min, size etc. is facade because both REST controllers and another modules communicate with it, but the problem is that javax validation annotation like #Valid are working only on REST Controller layer (in classes with annotation #RestController) and when I try to create some tests for this facade then fields with wrong values return NullPointerException instead of MethodArgumentNotValidException. I tried to create WebMvcTest but also returns wrong exception. Is it some solution for it? I saw that I could call some validator inside the method but it looks like much more complex approach than annotation on method's argument.

You can inject the javax.validation.Validator into any Spring component. For example, into a facade component, and perform validation in the facade layer:
#Autowired
Validator validator;
Set<ConstraintViolation<UserRequestDTO>> violations = validator.validate(userRequest);
This way you can remove the #Valid annotation from controllers at all. And this approach puts validation results under the your control.

Related

Spring boot: should validation been tested when testing controller layer

I am working on the project where I want to have decent test-infrastructure.
I am using spring boot, which makes easier for testing separate layers of the project: for example
If I want to test controller layer I will mock (with mockito) service dependencies of the controller, and check whether right service method will be called on given http request, and expected http status will be returned. If I want to test service layer I will mock repository and business logic dependencies. And so on.
In my project, I am using spring validators to check whether request body is passed correctly (with the use of #InitBinder method I am adding my custom validators to the WebDataBinder, and with use of #Valid annotation, those validators are called on the parsed request body).
So my question is: is it good practice to mock validators and test only controller logic (validators will be tested in context of validator layer)?
I am just not sure which is the best practice, and is it normal to test validators along with controllers?
Mocking is not always best option, when you are testing your controller logic, validation logic and especially business logic. I would not recommend to mock any of these.
You can use various framework to test:
Controller logic - RestAssured or MockMvc
Business logic - Plain JUnit tests under SpringBootTest and SpringRunner
Validation logic - Plain JUnit tests under SpringBootTest and
SpringRunner
For further reading:
RestAssured: http://rest-assured.io/
Spring validator test: Writing JUnit tests for Spring Validator implementation

Automatic invocation of Bean Validator for #Valid outside of Spring MVC

Simple scenario:-
In a Spring 4 app the following #Valid gets triggered when I make a REST call but not when I make an API call. The docs talks about it but does not state how to do it the way I want.
#RequestMapping(name="/something")
public Entity save(#Valid Entity e){ return repo.save(e);}
Without writing any custom AOP code to achieve this myself etc. how do I get bean validation #Valid triggered in Spring ? Looking for any Spring or Hibernate configuration that will turn this on for simple API calls.
Example: When I bundle my component as a maven I would like to get my beans validated irrespective of whether they run in a web context or outside , say Spring Batch or just JUnit Tests.
And when I bundle this jar in a web app I definitely don't want this executed twice.

When to use #RestController vs #RepositoryRestResource

I have been looking at various examples of how to use Spring with REST. Our end target is a Spring HATEOAS/HAL setup
I have seen two distinct methods for rendering REST within Spring
Via #RestController within a Controller
Via #RepositoryRestResource within a Repository
The thing I am struggling to find is why would you use one over the other. When trying to implement HAL which is best?
Our database backend is Neo4j.
Ok, so the short story is that you want to use the #RepositoryRestResource since this creates a HATEOAS service with Spring JPA.
As you can see here adding this annotation and linking it to your Pojo you have a fully functional HATEOAS service without having to implement the repository method or the REST service methods
If you add the #RestController then you have to implement each method that you want to expose on your own and also it does not export this to a HATEOAS format.
There is a third (and fourth) option that you have not outlined, which is to use either #BasePathAwareController or #RepositoryRestController, depending on whether you are performing entity-specific actions or not.
#RepositoryRestResource is used to set options on the public Repository interface - it will automatically create endpoints as appropriate based on the type of Repository that is being extended (i.e. CrudRepository/PagingAndSortingRepository/etc).
#BasePathAwareController and #RepositoryRestController are used when you want to manually create endpoints, but want to use the Spring Data REST configurations that you have set up.
If you use #RestController, you will create a parallel set of endpoints with different configuration options - i.e. a different message converter, different error handlers, etc - but they will happily coexist (and probably cause confusion).
Specific documentation can be found here.
Well, above answers are correct in their context still I am giving you practical example.
In many scenarios as a part of API we need to provide endpoints for searching an entity based on certain criteria. Now using JPA you don't have to even write queries, just make an interface and methods with specific nomenclature of Spring-JPA. To expose such APIs you will make Service layer which would simply call these repository methods and finally Controllers which will expose endpoints by calling Service layer.
What Spring did here, allow you to expose these endpoints from such interfaces (repositories) which are generally GET calls to search entity and in background generates necessary files to create final endpoints. So if you are using #RepositoryRestResource then there is no need to make Service/Controller layer.
On the other hand #RestController is a controller that specifically deals with json data and rest work as a controller. In short #Controller + #ResponseBody = #RestController.
Hope this helps.
See my working example and blog for the same:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with-hibernate-no-controller
#RepositoryRestController override default generated Spring Data REST controllers from exposed repository.
To take advantage of Spring Data REST’s settings, message converters, exception handling, and more, use the #RepositoryRestController annotation instead of a standard Spring MVC #Controller or #RestController
E.g this controllers use spring.data.rest.basePath Spring Boot setting as base path for routing.
See Overriding Spring Data REST Response Handlers.
Be aware of adding #ResponseBody as it is missed in #RepositoryRestController
If you not exposed repository (marked as #RepositoryRestResource(exported = false)), use #BasePathAwareController annotation instead
Also be aware of bags
ControllerLinkBuilder does not take Spring Data REST's base path into account and #RequestMapping shouldn't be used on class/type level
and
Base path doesn't show up in HAL
Workaround to fix link: https://stackoverflow.com/a/51736503/548473
UPDATE: at last I prefer not to use #RepositoryRestController due to lot of workarounds.

Testing Spring Webflow Action Classes

I am writing test case for my webflow using org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests
public class MyFlowExecutionTests extends AbstractXmlFlowExecutionTests {
}
In some cases my logic is simple, So I invoke my service layer directly from the Spring webflow.
In some cases I use an extenstion of org.springframework.webflow.action.MultiAction classes and I invoke my service layer from the action classes.
In the first scenario, wrting test case is straight forward. In the second scenario, I found it really complex to write the test cases using org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests for the Action class.
In the first scenario, I can mock all the service classes used from my flow. In the second scenario, using easy mock class extension, I can mock the action class. But then I need to mock the service layers used inside, which I think mock can't handle that well.
I am now thinking of somehow moving the Action class code to Spring EL. Or Anybody have a better idea for testing the action class code along with webflow code?

How to add a custom annotation to Spring MVC?

Can anyone explain what I need to do to implement my own annotation that would add functionality to my web requests?
For example:
#Controller
public class MyController {
#RequestMapping("/abc")
#RequiresSomeSpecialHandling
public void handleSecureRequest() {
}
}
Here #RequiresSomeSpecialHandling would be my own annotation that causes some special work to be done before or after the given web request /abc.
I know that on a very high level I would need to write a bean post processor, scan classes for my annotations, and inject custom mvc interceptors when needed. But are there any shortcuts to simplify this task? Especially for the two examples above.
Thanks in advance,
This kind of Annotations, (that add additional functionality when invoking a method) looks like annotations that trigger an AOP Advice.
#see Spring Reference Chapter 7. Aspect Oriented Programming with Spring
The idea is to use the Annotation to trigger the AOP Advice.
like:
#Pointcut("#target(com.example.RequiresAuth)")
Depends on what you want to do as a result of #RequiresSomeSpecialHandling. E.g. do you want it to influence request mappings or the invocation of the method (i.e. resolving method arguments, processing the return value)?
The support for annotated classes in Spring 3.1 became much more customizable. You can browse some examples in this repo.
Also keep in mind that a HandlerInterceptor in Spring 3.1 can cast the handler Object to HandlerMethod, which gives you access to the exact method including its annotations. That may be enough for what you need to do.
If caching is one of your goals, take a look at the #Cacheable annotation (and its siblings #CachePut, #CacheEvict and #Caching), available as of Spring 3.1.

Resources