【问题标题】:How to design endpoints for bi-directional entity mapping如何为双向实体映射设计端点
【发布时间】:2022-01-01 14:44:41
【问题描述】:

有两个实体,UserOrderUser 实体有一个Set<Order> 的订单,它是一个双向映射。

现在我有两个控制器,一个控制器叫做OrderController,它有一些端点来检索所有订单等。第二个控制器叫做UserController,它有一些与用户相关的端点,但它也有/users/{username}/orders/users/{username}/orders/{orderId} 等端点。

问题是我应该在哪里添加端点来持久化订单?它应该是OrderController 中的POST,即/orders,还是应该在UserController 中作为/users/{username}/orders 端点?订单由用户创建,OrderController 仅用于检索所有订单,而不仅仅针对特定用户。

你对它应该如何设计有什么建议吗?

【问题讨论】:

  • 我不会在用户下嵌套订单。仅仅因为用户拥有一组订单并不意味着它“拥有”这些订单。如果它们是具有自己 id 的独立持久实体 - 即全局唯一,则只需 /orders/orderid
  • 这种情况下订单是依赖于用户的,因为当我们删除一个用户时,他的所有订单都会被删除。用户应该能够添加订单、编辑订单等,所以我相信用户控制器中应该有一个端点。订单控制器用于查看所有订单。 WDYT?

标签: java spring rest jpa spring-rest


【解决方案1】:

Zalando API Guideline 对这个问题有一些看法,他们建议我们应该限制资源类型的数量,原因如下:

为了保持维护和服务发展的可控性,我们应该遵循 “功能分割”和“关注点分离”设计 原则,不要将不同的业务功能混在同一个 API 定义。在实践中,这意味着资源的数量 通过 API 公开的类型应该受到限制。在这种情况下,资源 类型被定义为一组高度相关的资源,例如 集合、其成员和任何直接子资源。

适用于您的情况,基本上他们建议只有以下资源类型:

  • /用户
  • /订单

并且没有必要让/users/{username}/orders//orders 已经用于相同的目的。如果您想为用户获取订单,只需使用/orders?user=foobar

【讨论】:

  • 在这种情况下,我是否需要对用户调用`getOrders()` 方法,或者在存储库中创建一个新方法来检索用户的所有订单是否有意义?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多