【问题标题】:REST API Design for Save action that also has optional side effects [closed]用于保存操作的 REST API 设计也具有可选的副作用 [关闭]
【发布时间】:2020-03-14 16:39:30
【问题描述】:

我正在尝试为大多数 CRUD 操作设计一个 RESTful Web API。

我有一个设计难题,即如何为实体建模保存操作,该实体还可能具有可选的副作用,例如更新不属于原始实体的其他“子”实体。

例子:

  • 模板实体
  • 子文档实体

模板可以有多个子文档 如果更新了模板,则可以更新基于实体的所有或部分子级。

GET /templates/{id} -> Returns template
POST /templates/ -> Creates template
PUT /templates/ -> Updates template

现在,如果我们要更新模板,并且还要指示服务器根据模板更新所有文档,什么是好的设计?

1)

PUT /templates/ 
{
  template: {
    ..
  },
  childDocumentsIds: [1, 3, 7...]
}

2)

PUT /templates?childDocumentIds=1,3,7
{
template
}

已经提出了类似的问题,但它们并没有完全回答我的问题:

我试图判断其他人在设计 REST API 时是否有类似的问题。最近在体验了其中的一些之后,我认为我们可以比 REST API 做得更好

【问题讨论】:

    标签: rest api


    【解决方案1】:

    我认为我们可以比 REST API 做得更好。

    REST 架构约束的设计考虑了一个特定问题:“跨多个组织的基于网络的长期应用程序”。 REST 的参考应用程序是万维网。如果这不是您遇到的那种问题,那么 REST 可能不合适。

    HTTP 是一个应用程序,其应用程序域是通过网络传输文档。如果您可以将问题描述为通过网络传输文档,那么您已经为您完成了一大堆工作,如果您愿意遵守它的约束,您可以利用它。

    HTTP 中的远程创作习惯用法(主要是 GET/PUT)非常粗鲁——请给我一些文档的最新表示;这是我对一些文件的最新表示,请让您的副本看起来像我的。我们的 API 是一个门面——我们假装是一个理解 GET 和 PUT 语义的愚蠢文档存储,但在幕后我们做了有用的工作。

    例如,我们可能有一个简单的待办事项列表。一开始是空的

    GET /todoList
    
    200 OK
    
    []
    

    如果我们想向 Bob 发送电子邮件,我们将首先编辑文档的本地副本。

    ["Send an email to bob@example.org"]
    

    然后我们会要求服务器使它的文档副本看起来像我们的副本

    PUT /todoList
    
    ["Send an email to bob@example.org"]
    

    HTTP 语义告诉服务器如何解释这个消息,但它可以自己选择如何处理它。例如,服务器可能会更新它自己的 /todoList 本地副本,将电子邮件发送给 Bob,更新其 /recentlySentEmail 的表示形式,更新其 /recentlySentEmailsToBob 的表示形式,等等。

    来自服务器的响应采用多种标准形式; 202 Accepted -- 你的要求我明白了,我可以稍后再做; 204 -- No Content -- 我编辑了我的文档副本以匹配你的,这里有一些元数据; 200 OK -- 我已经对我的文档表示进行了更改,在这里它们是(或者,我已经对我的文档副本进行了更改,你可以向我索要更新的副本)。

    如果我们要更新模板,同时还要指示服务器根据模板更新所有文档,什么是好的设计?

    最直接的例子是只发送修改后的模板,并允许服务器在它认为合适的时候更新其他资源

    GET /template
    
    200 ....
    [original representation of template]
    
    // make edits
    
    PUT /template
    [revised representation of template]
    
    200 OK
    

    如果服务器知道哪些文档需要更新,它就可以更新它们。达达。

    如果客户端需要知道哪些资源已更新,只需将该列表发回

    PUT /template
    [revised representation of template]
    
    200 OK
    
    [URI of resources changed by the template]
    

    了解如何使用网站实现结果可能是一项有用的设计练习。怎么可能。你会得到一个包含表单的资源;表单可能包含一个文本区域,其中包含模板的某些字符串表示形式。您可以将表单中的表示替换为您想要的表示,然后提交表单,将模板携带到服务器。它会进行更改,然后为您返回一个新表单,其中包含将受更改影响的不同资源的复选框,允许您更改默认选择。您将提交该表单,然后服务器可以进行适当的更改。

    这就是 REST——因为您使用的是标准化的媒体类型,通用组件(如浏览器)可以完成所有 HTTP 和 HTML 簿记工作。浏览器知道表单是如何工作的,它知道如何利用表单处理规则和元数据来创建适当的请求。网络缓存都知道哪些表示可以存储,哪些应该失效。

    【讨论】:

    • 感谢您抽出宝贵时间回答这个问题。我完全理解。多年来,我设计了许多用户在生产系统中使用的许多 REST API。还将客户端实现为 Android 应用程序、JS 前端。即使经过多年的 REST API 设计,我仍然对如何为请求建模感到困惑。而且我不是唯一一个。 “我认为我们可以做得更好”更多地意味着更多关于 REST 设计的规则,或者更多地意味着将 REST 用于更通用的东西(如 GraphQL)。带着这个问题,我想衡量还有谁和我一样痛苦。
    • 想一想,Stack Overflow 可能不是发布此内容的正确位置。我很可能会删除这个问题。
    • 是的,“我想谈谈……”这个空间有很大的差距。
    猜你喜欢
    • 2017-06-04
    • 1970-01-01
    • 2011-09-27
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    相关资源
    最近更新 更多