REST API设计 - PUT请求的资源关系和幂等性:完全资源表示的确切含义是什么?

时间:2015-04-04 17:45:42

标签: rest put idempotent

我理解,对于部分更新,必须采取不是幂等的动作。为此,一种有效的方法是向该资源发出POST请求。

我对相关资源有疑问。例如,想象以下资源及其属性:

  1. 帐户
    标识
    名称
    帐号#
    用户(集合)

  2. 用户
    标识
    姓名

  3. 现在想象一下,我想对帐户进行部分更新 - 例如,更改帐户名称。

    我可以将以下请求作为有效的部分更新:

    POST /account/id/123
    
    {
        "name" : "My New Name"
    }
    

    我的问题是关于完整的PUT请求必须是幂等的,并且必须包含资源的完整表示

    我可以将以下内容作为有效的幂等请求吗?

    PUT /account/id/123
    
    {
        "name" : "My New Name",
        "accountNumber" : "654-345-4323"
    }
    

    这被视为有效的幂等行为吗?我已经包括了所有顶级"帐户"信息,但我对此提出质疑,因为我也没有发布属于该帐户的所有USERS

    为了成为有效的幂等请求,我是否需要在PUT请求中包含所有子资源?

2 个答案:

答案 0 :(得分:1)

如果要将PUT请求设计为完全资源替换,则这意味着您还需要为资源的所有可分配(可编辑)属性分配值,包括资源的关系(链接)。否则,未设置的属性将被视为设置为null

对于部分请求,您可以使用PATCH HTTP方法。如果你的资源表示足够简单,你可以使用部分更新,那么还有一个PUT约定。

PATCH vs. PUT

引用:

  

PATCH与PUT

     

HTTP RFC指定PUT必须采用全新资源   表示为请求实体。这意味着,例如,如果   只提供某些属性,应删除这些属性(即设置   为null)。

     

最近提出了另一种称为PATCH的方法。该   这个调用的语义就像PUT一样,它更新了一个资源,但是   与PUT不同,它应用delta而不是替换整个   资源。在撰写本文时,PATCH仍然是一个提议的标准   等待最终批准。

     

对于简单的资源表示,差异通常不是   很重要,许多API只是将PUT实现为PATCH的同义词。   这通常不会产生任何问题,因为它不常见   你需要将属性设置为null,如果需要,你可以   总是明确地包含它。

     

然而,对于更复杂的表示,尤其是包括列表,   能够准确表达变化变得非常重要   你想做。因此,现在我向两者提出建议   提供PATCH和PUT,并使PATCH做相对更新并具有   PUT替换整个资源。

     

重要的是要意识到PATCH的请求实体是a   不同的内容类型,它正在修改的实体。代替   作为一个完整的资源,它是一种描述的资源   对资源进行的修改。对于JSON数据模型,其中   正是这篇文章所倡导的,我相信有两篇   明智的方法来定义补丁格式。

     
      
  1. 非正式的方法,你接受一个部分的字典   对象的表示。只有存在的属性是   更新。不存在的属性保持不变。这种方法   很简单,但它有一个缺点,如果资源有一个复杂的   内部结构例如包含一大堆dicts,那就是   需要在实体中给出完整的dicts列表。有效地补丁   再次变得类似于PUT。
  2.   
  3. 更正式的方法是   接受修改列表。每次修改都可以是dict   指定要修改的节点的JSON路径,修改   ('添加','删除','更改')和新值。
  4.   

答案 1 :(得分:1)

更容易理解的方法是考虑PUT方法忽略目标资源的当前状态,因此“完整资源表示”意味着它必须具有替换现有资源所需的所有数据新资源。

在您的示例中,这可能是没有用户的帐户的有效完整代表。

服务器在缺少某些内容时可以采用默认值,但应该正确记录,因为某些用户可能会对部分更新感到困惑。