REST:如何更新一行并在同一请求上创建零个或多个其他资源?

REST: How to update a row and create zero or more of other resource on same request?

我会尽量简化这个问题,这可能是个愚蠢的问题。

我正在重写一个已有 7 年历史的 Web 应用程序(帮助台软件)。需要使其成为 REST API 以供不同客户端 Web 浏览器和移动应用程序使用。还需要使业务逻辑尽可能接近目前运行良好的原始逻辑。

当前关于 REST 的斗争:

我需要的是更新资源 /tickets/47321

如果此资源的 status_id 发生更改,则需要保存此更改的记录,两者都在同一个数据库事务中,因为它需要 全有或全无。这就是原始应用程序的工作方式,我们希望保持这种行为。

所以问题是:

我可以 PUTtickets/47321 整个资源或部分状态表示来更新驻留在服务器中的资源并创建历史更改的新记录(如果 status_id 不同) 和 return 它们都以 JSON:

的形式返回给客户端
 {
    ticket: {}, // new ticket state
    history: {} // the new created record of history change 
 }

如果有 return?

,客户端可以通过这种方式更新 ticket 并将历史添加到历史更改列表中

从技术上讲,是的,您可以做到这一点。但是,它可能不像 return 并排放置 2 个对象那么简单;查看 Richardson Maturity Model (Level 1),人们会期望在之后收到相同类型的资源 调用 (PUT) api 端点。

也就是说,您可以从工单中嵌入额外的资源(将历史更改附加到工单,在 Hypertext Application Language (HAL) proposed draft specification), or better yet (if you're aiming towards REST level 3), provide a link relationship, in conformity with the "Target IRI" defined in Web Linking specification (RFC 5988 之后):

    例如,
  • /api:history?ticketId=47321 将 return 属于该工单的所有历史记录,按创建日期分页和排序(您可以只 select 最新的)
  • /api:history?id=123 你会在服务器上做一些工作以确保它直接指向最新的历史记录(与该票证 ID 相关)

关于部分更新,查看RFC 6902(它定义了补丁标准),从客户端的角度来看,API可以被称为

PATCH /ticket/47321

[
    { "op": "replace", "path": "/author", "value": "David"},
    { "op": "replace", "path": "/statusId", "value": "1"}
]

可以找到更多示例 here