RESTAPI设计-处理外键引用和同一资源的不同表示

RESTAPI设计-处理外键引用和同一资源的不同表示,rest,web-applications,api-design,Rest,Web Applications,Api Design,在创建API时,我常常不确定如何处理数据库中的引用值以及同一资源的不同表示形式 GET /api/order/1 { id: 1, status_id: 1, } 假设我有一个订单表,其中包括以下字段:id、product_id(fk)status_id(fk) 现在,向该订单发出GET请求: GET /api/order/{order_id}. 由于我缺乏经验,现在出现了两个问题: 1。引用其他资源(产品)或查找表(状态)的字段返回什么? 我正在考虑的方案有: a) 仅提供fk

在创建API时,我常常不确定如何处理数据库中的引用值以及同一资源的不同表示形式

GET /api/order/1
{
  id: 1,
  status_id: 1,
}
假设我有一个订单表,其中包括以下字段:id、product_id(fk)status_id(fk)

现在,向该订单发出GET请求:

GET /api/order/{order_id}. 
由于我缺乏经验,现在出现了两个问题:

1。引用其他资源(产品)或查找表(状态)的字段返回什么?

我正在考虑的方案有:

a) 仅提供fk id,然后将其留给客户端请求相应的资源

GET /api/order/1
{
  id: 1,
  status_id: 1,
}
b) 提供id以及响应中可能相关的值。例如,答复将包括:

GET /api/order/1
{
  id: 1,
  status_id: 1,
  status_title: 'pending,
}
c) 在后端执行两个查询,并将它们嵌套在响应中:

GET /api/order/1
{
  id: 1,
  status: {
   id: 1,
   title: 'pending',
  },
}
2。您如何处理不同利益相关者对此资源的请求?

例如,获得订单的客户肯定不应该(也可能不希望)访问该资源的相同表示形式,因为商店管理员使用其界面来完成订单

比如说,理论上,订单表包含一个字段佣金率,说明 相关委员会就该命令进行了内部谈判

您现在如何处理前面提到的GET,以表明您正试图从某个角度检索它

或许

GET/api/order/{id}/customer


GET/api/order/{1}?view=customer

api通常在域级别工作:

Order {
  id: "123",
  customerId: "456"
  ...
}

数据库在实现级别工作:

带有FK等的行。任何客户端都不需要知道FK是什么意思,甚至不需要看到FK

因此,从域的角度开始设计API,然后将端点分组到授权上下文中是一个好主意,例如,只有销售代表才能请求订单的佣金率

域对象本身是“头等公民”、
订单
产品
销售
等,授权上下文决定了谁/什么可以请求每个域对象(REST资源)

e、 g.
客户
可能想知道他们的
订单
何时将
交付
,而
销售代表
可能想知道该
客户
订单
何时交付,以便他们可以获得他们的
佣金率

GET /order/{id} -> Order accessed by (Custmer, SalesRep, Admin)
GET /order/{id}/status -> OrderStatus accessed by (Custmer, SalesRep, Admin)
GET /order/{id}/commission -> CommissionRate accessed by (SalesRep, Admin)

在每次调用中,客户机都希望了解
订单的特定方面。就包含其他内容而言,他们可能不想要它,但您可以在响应中包含相关链接作为扩展,提供与该
订单
相关的API端点,例如
产品
订单,甚至是获取
状态
等的API端点。

“API倾向于在域级别工作”提出了一个很好的观点,可能回答了我的大部分问题。哈特奥斯的概念,然后可以工作的休息。这种想法现在引导我去探索像GraphQL这样的选项,它似乎将更多的统一性放在客户机上。这对于缓解我试图回避的过度/不足请求应该是很好的。