Spring data validation and business rule validation

I want to find the best practice for applying business rules when working with spring rest.

Consider the following scenario:

  • I have a Customer and Order relationship in @OneToMany .
  • I have a business rule stating that Customer must have a flag flag set to execute orders

Therefore, I need to make sure that whenever someone POST before /orders the Customer call is made.

I am considering using beforeSave Validators to auto-increment other services / repositories in Validator and check everything that needs to be checked.

Is there a better way to achieve the same?

+5
source share
3 answers

There are several ways to solve this problem. As far as I know:

  • Use spring security annotations like @PreAuthorize . The intended use of these annotations, however, is for security purposes only, and you indicate the business rules. I would use them for Spring user authorization rules data security chapter

  • Using validators, as you mentioned yourself. Spring data validators

  • Use spring data break events Spring events to save data . You can create global event handlers, however here you need to determine the type of entity. I would go with Annotated handled event handlers to execute Spring business logic handler handled by a data handler

+1
source

One solution that you can use to solve problems related to your business rules is using Spring AOP. What you can do is define an annotation (e.g. @X) and place that annotation on top of your POST request.

 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface X{} 

Next, you need to do, create an aspect and run your validation logic in this aspect as follows:

 @Aspect @Component public class CustomAspect { //You can autowire beans here @Around("@annotation(qualified name of X)") public Object customMethod(ProceedingJoinPoint joinPoint) throws Throwable { flag = customLogic(); if (flag){ return joinPoint.proceed(); //return if logic passes, otherwise }else{ throw new BusinessRuleException("Business rule violated"); } } private boolean customLogic(){ //your custom logic goes here } } 

And finally, apply this annotation on top of any method in the controller layer, for example:

 @X @RequestMapping(method = RequestMethod.POST, value = "do-something") public void callSomething(HttpServletRequest request) throws Exception { // your business logic goes here } 

The only thing to note above is that you must explicitly pass the HttpServletRequest request to your controller method so that the AOP aspect gets the same context for manipulating attributes associated with the user's session, such as session_id, etc.

The above solution will help you add business rules on top of your business logic and will help you with all kinds of preliminary checks that you want to create in your web application. This is a pretty handy Spring AOP application. Stretch out in case of any

0
source

So, for the sake of the whole world, I am adding my solution. Went with number 2.

The documentation is pretty clear on how to proceed, simply by sharing a few tips that can save you time.

how

 /** * "beforeSave" gets called on PATCH/PUT methods * "beforeCreate" on POST * "beforeDelete" on DELETE */ enum Event { ON_CREATE("beforeCreate"), ON_UPDATE("beforeSave"), ON_DELETE("beforeDelete"); private String name; Event(String name) { this.name = name; } } ... private static void addValidatorForEvents(ValidatingRepositoryEventListener eventListener, Validator validator, Event... events) { Arrays.asList(events).forEach(event -> eventListener.addValidator(event.name, validator)); } 
0
source

Source: https://habr.com/ru/post/1275377/