【问题标题】:Updating composite entities in a RESTful resource更新 RESTful 资源中的复合实体
【发布时间】:2015-05-25 13:52:45
【问题描述】:

我有一个具有多个属性的实体,比如«project»。除了简单的属性,项目可能有一个«状态»列表,其中最后一个是当前的。我有一个 Web 表单来创建/编辑项目。该项目的所有属性都可以在此表单中更改,用户也可以为项目添加新状态(但不能更改或删除旧状态)。

项目状态是纯粹的复合实体,它们在项目范围之外没有任何独特的意义或身份,也不能直接解决,因此它们显然不值得一个特殊的根 REST 资源。

根据 REST 架构,我创建了一个名为 /projects 的资源。 POST 用于创建新项目,PUT 用于更改现有项目。

但是,我不希望客户将项目及其所有历史状态放在一起,首先是因为这个集合太重了,其次是因为业务逻辑只允许添加状态,而不是更改或删除它们,所以无论如何,将项目及其所有状态放在一起没有任何意义。

PUT 一个只有新状态的项目也不是一种选择,因为它违反了 PUT 的幂等性。

我也不喜欢在第二个 HTTP 请求中发布状态的想法,比如 /project/{id}/status,因为从用户的角度来看,这会破坏更新操作的原子性。如果第二个请求在网络上丢失,那么项目对于编辑它的用户将显得不一致(属性已更改,但状态保持不变)。对于更新看似单一的实体这一简单任务,创建 RESTful “事务”似乎有点过头(而且容易出错)。

这种问题在我的工作中非常普遍,可以概括为:更新业务逻辑只允许部分更新的复杂复合实体的 REST 完全正确和原子方式是什么?

【问题讨论】:

    标签: rest restful-architecture


    【解决方案1】:

    我认为如果你想做部分更新(实际上是你的情况),你应该使用方法PATCH。这允许更新没有依赖项(状态)的项目或没有项目提示的依赖项。

    您会注意到在方法PATCH 中有一种描述要执行的操作的格式。它被称为 JSON 补丁(参见 https://www.rfc-editor.org/rfc/rfc6902)。这种格式描述了您希望在请求中执行的操作:添加元素、更新元素、删除元素……

    我认为,如果您想(例如)更新特定项目的名称、删除状态(这也是一个示例,因为我读到您想禁止这样做!)并添加一个新的一对一原子请求:

    PATCH /projects/1
    [
        {
            "op": "replace",
            "path": "/name",
            "value": "the new name of the project"
        },
        {
            "op": "remove",
            "path": "/statuses/1"
        },
        {
            "op": "add",
            "path": "/statuses/",
            "value": {
               "name": "my status",
              (...)
            }
        }
    ]
    

    请注意,您可以将您想要的内容放在属性name 中,以标识资源状态中的相关元素。所以/statuses/1 可以是数组中的第二个元素,id 值为1 的状态或其他。

    请求的服务器端处理可以是原子的。

    我写了一篇关于批量更新的博文:https://templth.wordpress.com/2015/05/14/implementing-bulk-updates-within-restful-services/。我认为“实施批量更新”部分可能与您要查找的内容相对应。

    希望对你有帮助, 蒂埃里

    【讨论】:

    • 哇。我不知道这个 RFC。谢谢!
    • 不客气!很高兴听到这对您有帮助!
    【解决方案2】:

    您需要 HTTP PATCH 吗?它是表示对资源的增量更新的动词。

    https://www.rfc-editor.org/rfc/rfc5789

    【讨论】:

    • 根据 RFC,这似乎是我想要的。但我一直认为 PATCH 方法有点像 hack,并且不确定它如何适合 REST 架构。大多数对 REST 的描述根本没有提到 PATCH 方法。我知道 REST 只是一种架构模式,而不是标准,但仍然有任何关于 PATCH 如何适合整个 REST 架构的“规范”信息来源?
    • REST 提倡根据上下文在资源/实体上使用 HTTP 动词(GET、POST、...)。使用 HTTP PATCH 对资源/实体进行部分更新与 RESTful 一样。确实 PATCH 似乎被遗忘/忽略了,但仅此而已。它有很多原因,但没有一个是因为它的使用可能与 RESTful 设计冲突。
    猜你喜欢
    • 2014-08-29
    • 2012-02-21
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 2013-07-26
    相关资源
    最近更新 更多