假设我们有两个实体。User实体可以有许多报价,而Offer必须有一个User。
class User {
...
@OneToMany(mappedBy = "user", orphanRemoval = true)
private Set<Offer> offers;
}
class Offer {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fk_user")
private User user;
}此时有两个控制器。UserController和OrderController。UserController在/api/v1/users/下映射,OrderController映射在/api/v1/orders/下。
Offer修改或删除User?如果我们让/api/v1/users/{username}/offers/{offerId}删除或更新报价,我们是否也应该有允许编辑或删除报价的/api/v1/offers/{offerId}端点?也许对管理员来说,拥有它值得吗?发布于 2022-01-21 17:59:39
我在创建端点时使用的一般经验规则是:
不过,我不确定是否有一条成文的规则,确切地说应该如何构建一个URL。在您的具体情况下,只有在您公开和使用优惠的唯一位置时,我才会使用/users/{username}/offers/{offerId},因为您是根据功能将代码分隔开的。
如果您有更多关于要约的逻辑和/或具有这种逻辑的bean,我将为/offers下的报价创建一个单独的控制器。关于你最后一个问题。这在很大程度上取决于你在努力实现什么。如果您需要能够更新/删除/创建服务,那么拥有这样的功能是有意义的。即使它仅由管理员使用。可以限制对端点的访问。如何做到这一点取决于您授权用户的方式以及您拥有的有关用户的信息。大多数人都使用角色。
如果您决定拥有完整的CRUD功能,我建议使用单一路径并结合请求方法。
就我个人而言,我要创造以下几点:
@RestController
@RequestMapping(value = "/users")
class UserController {
@GetMapping("{userId}/offers")
public Set<Offer> getAllOffers(@PathVariable("userId") String userId){
...
}
@GetMapping("{userId}/offers")
public Offer getOffer(@PathVariable("userId") String userId, @RequestParam(required = true) String offerId){
...
}
@PutMapping("{userId}/offers")
public Offer createOffer(@PathVariable("userId") String userId, @RequestBody Offer offer){
...
}
@PostMapping("{userId}/offers")
public Offer updateOffer(@PathVariable("userId") String userId, @RequestBody Offer offer){
...
}
@DeleteMapping("{userId}/offers")
public void deleteOffer(@PathVariable("userId") String userId, @RequestParam(required = true) String offerId){
...
}
}在这种情况下,我认为创建和更新的POST/PUT将更干净,因为信息不会重复。准确地说是身份证。
发布于 2022-01-21 17:25:56
我同意它应该位于相同的“UserController”中,这是有意义的,因为提供服务属于用户,因此有一个端点,如:
@GetMapping("{user}/offers")
public Set<OfferDTO> getOffers(@PathVariable("user") String user) {
return offerService.getOffers(user);
}例如,如果您想在列表中显示元数据,您可以定义特殊的DTO,以便从报价中获取元数据,并且可以将它们作为列表显示给用户。
您可以设置一个类似的端点,用于更新服务(可以是POST端点)和删除端点(用于删除)。不过,您可能想一想,如果用户在删除某个报价时,它会发生什么情况,比如在后台线程中执行异步任务,并更新UI以通知用户该提议已被删除。
Spring有一些非常好的安全注释(检查这和这),您可以为管理员端点编写自己的注释:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAuthority('" + ROLE_ADMIN + "')")
public @interface IsAdmin {}然后按如下方式注释您的方法:
@DeleteMapping("/{user}/{offer}/delete")
@IsReceiverAdmin
public void delete(@PathVariable("user") String user, @PathVariable("offer") String offer){
return offerService.delete(user, offer);
}当然,服务层的实现是非常重要的,但是它可以像调用存储库和在那里执行操作一样简单:)
https://stackoverflow.com/questions/70804976
复制相似问题