简体   繁体   English

最佳实践:Spring Boot后端和jQuery前端

[英]Best Practice: Spring Boot Backend & jQuery Frontend

I'm currently working on a project with a Spring Boot 2 Backend and a jQuery Frontend. 我目前正在使用Spring Boot 2后端和jQuery Frontend进行项目。 Thus the frontend sends Ajax request to spring REST controllers to operate with database entities. 因此,前端将Ajax请求发送到spring REST控制器以与数据库实体一起操作。

When it comes to create entities with foreign linked entities via those ajax calls (eg creating a person with multiple addresses), I'm asking myself what the best practice would be, while considering transactional operations and reducing redundant code. 当通过那些ajax调用来创建具有外部链接的实体的实体时(例如,创建具有多个地址的人),我问自己最好的做法是什么,同时考虑事务性操作并减少冗余代码。

I've thought about these possibilities yet: 我已经考虑过这些可能性:

  1. Several ajax calls Creating the linked entities with one ajax call per entity and check if they fail. 多个ajax调用创建链接的实体,每个实体一个ajax调用,并检查它们是否失败。 If one fails, delete all the created entities with ajax calls for each, like a manual rollback. 如果失败,则删除所有创建的具有ajax调用的实体,例如手动回滚。 Seems like a very bad concept. 似乎是一个非常糟糕的概念。

  2. One Ajax call sending all parameters Having one ajax call sending all necessary parameters for the entities that have to be created. 一个Ajax调用发送所有参数一个Ajax调用发送所有必须创建的实体的所有必要参数。 Then creating all the entities via the entity services server sided. 然后通过实体服务服务器端创建所有实体。 But how to operate transactional here? 但是如何在这里进行事务性操作? And how to reduce redundant code? 以及如何减少冗余代码?

Thanks in advance 提前致谢

First, I need to know which database you are using. 首先,我需要知道您正在使用哪个数据库。 If you are using MongoDB, then forget about the transactional part (unless you are using the version 4.0 and the transactional support). 如果您使用的是MongoDB,请忽略事务部分(除非您使用的是4.0版本和事务支持)。 So I guess you go for an SQL database. 因此,我想您选择一个SQL数据库。

The answer to your question may depend on how the frontend treats the data. 您问题的答案可能取决于前端如何处理数据。 For me, the 1st option makes no sense anyway. 对我来说,第一种选择无论如何都没有意义。 It seems like you either want to include all the addresses or no addresses at all, so I will just make one request with all the addresses because the whole data is treated like an indivisible set. 似乎您要么想要包含所有地址,要么根本不包含任何地址,所以我将只对所有地址发出一个请求,因为整个数据被视为不可分割的集合。

The transaction part can be easily solved using Hibernate and the transaction manager (Just annotate the method which saves the addresses as @Transactional and that's all) 使用Hibernate和事务管理器可以轻松解决事务部分(只需注释将地址保存为@Transactional的方法,仅此而已)

I would implement it like this: 我会这样实现:

The controller: 控制器:

@RestController
@RequestMapping("/users")
public class UserController {

  @Autowired
  private UserService userService;

  @PostMapping("/{userId}/address")
  public List<Address> addAddress(@PathVariable String userId,
      @RequestBody AddressInsertRequest request){

    return userService.updateAddresses(userId, request.getAddresses());
  }

  //Externalize to oter class
  public class AddressInsertRequest {

    private List<Address> addresses;

    public List<Address> getAddresses() {
      return addresses;
    }

    public void setAddresses(List<Address> addresses) {
      this.addresses = addresses;
    }
  }
}

The service: 服务:

public class UserService {

  //TODO Implement with hibernate
  private UserRepository userRepository;

  @Transactional
  public List<Address> updateAddresses(String userId, List<Address> addressList){
    User user = userRepository.findById(userId);
    user.setAddressList(addressList);
    userRepository.save(user);
    return user.getAddressList();
  }
}

You're right to consider transactionality. 您考虑交易性是正确的。 As you already indicate option 1 is a bad approach as it requires manual rollbabck. 正如您已经指出的那样,选项1是一种不好的方法,因为它需要手动执行rollbabck。 Option 2 seems the most legit, but it requires your backend to handle the rollback. 选项2似乎是最合法的选择,但它需要您的后端来处理回滚。 Which should be easy enough if a proper TransactionManager is configured. 如果配置了正确的TransactionManager,这应该很容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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