简体   繁体   中英

Call repository and service from controller layer with Spring

I use Spring Boot and Spring Data.

I have no problem in my mind to separate Repository Layer and Service Layer

So I have my UserRepository with CRUD method and some Spring Data method

  • findAll
  • findByUsername

I also have UserService with business method.

  • checkPassword(String login,String password)
  • businessMethodAction(String username)

Here is my question:

In my controller I have to call method from UserService and sometime from UserRepository. For the moment, I inject both in my controller, and I call service or repository

@Inject
UserService userService;

@Inject
UserRepository userRepository;

@RequestMapping("{username}")
private void myMethod(@PathVariable String username){
    return userRepository.findOne(username);
}

@RequestMapping("{username}/doBusineesAction")
private void myMethod(@PathVariable String username){
    return userService.doLogicalThin(username);
}

I'm just asking because I confused to inject both and to call one or the other in the same class

On another side, this would mean to duplicate method in service layer like this

public User findOne(String username){
 return userRepository.findOne(username);
}

What's your opinion?

Controller layer shouldn't ever call repository directly. You should always use the service layer because the service layer encapsulates your business logic surrounding that call. Just because currently there isn't any business logic, doesn't mean that you should skip the layer entirely.

In my opinion, the service layer must implement the business logic and it must be called from controllers. In most of the cases, this layer has to perform more operations than just calling a method from a DAO object. This is probably the best solution if your application has great size. Also, you can split your logic into several parts and make it working in one transaction, that help you to save the data in the non-controversial state.

If your controller does not require business logic or perform a single repository operation, you can use the repositories directly. Use services to implement use cases that require business logic or orchestration of repository calls.

If it's a layered CRUD app, I think it's fine for the controller to have knowledge of the repository and directly call it for simple read operations as long as the app is simple, small

Tradeoffs:

  • The controller calling the repo removes the layer of abstraction of the service layer
  • The controller and repository are now coupled
  • If you don't have requirements/use cases/business logic for your read op., I would suggest not rolling out a full service. YAGNI (you aren't going to need it). Meaning, it doesn't make sense to implement an extra 'pass through' service layer at this time given the business needs.
  • Before you choose to make your controller aware of your repository, I suggest to consider whether or not you've decoupled your repository layer from your persistence layer.

The structure of controller -> service -> repository -> persistence is not a hard and fast rule, as opposed to controller -> repository -> persistence . Your use case seems to fit the latter.

One approach is to reserve controllers are for business level concepts displayed on the views and repositories for the normalized entities in the DB. One can then define services to address the many-to-many relationship between controllers and repositories.

如果您使用的是弹簧启动,则正确的注释是@Autowired ,而不是@Inject

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM