使用带有不完整表示的PUT方法

PUT预期的标准行为是什么,并且资源不完整?

例如,我在/api/users/1上有一个User ,由下面的HAL json表示:

{'id': 1,
 'username': 'joedoe',
 'email': 'joe@doe.com',
 'password_hash': '9039dmk38f84uf4029i339kf32f0932i',
 'last_visit': '2013-11-04 21:09:01',
 'public': true,
 '_links': {'self': {'href': 'http://foo.bar.com/api/users/1'}}

}

然后,我做了一个PUT请求来更改usernameemail ,其中一个表示缺少其他属性:

PUT /api/users/1

{'username': 'joeydoey',
 'email': 'joey@doey.com'}

到目前为止,我一直认为这应该被看作是一个错误,因为它意味着一个部分更新,但是这个答案让我想到了它,并且说一个不完整的表示仍然是一个完整的替代方案,它给了服务器自由填补缺席的空白。

我无法在HTTP标准中找到任何与此相关的内容,所以我必须问,在这种情况下,预期的标准化行为是什么?

  • 它应该会导致错误,因为它意味着部分更新。 PUT有效载荷的模式应该与使用GET检索相同资源和媒体类型的模式相同。

  • 它应该是成功的,因为服务器可以自由地填充空白以及该媒体类型的默认值。 在这种情况下,它会将密码重置为空白或默认密码并相应地刷新哈希值,并将last_visit和public值设置为默认值。 当您考虑HATEOAS时,如果客户端提交服务器返回的相同媒体类型,此选项会更有意义,因为它无法预测超媒体控件如何更改,每次客户端不是每次都是不完整的不发送所有超链接,并且服务器必须相应地重置它们。

  • 1和2都是有效的,因为没有标准化的行为,并且由媒体类型决定如何处理它。 这并不正确,因为PUT不是从属于资源本身,而是取而代之。

  • 请记住,我不是在问什么是对的或什么是有道理的。 我在问哪一个标准支持。


    只要PUT的结果是从客户对资源的理解中完全替代(即,未通过的那些属性的先前值不会影响它们在PUT后的值),它应该成功。 然而,它看起来有点令人困惑,因为许多人倾向于将PUT的这种使用与场级更新语义(而不是完全替代)等同起来。

    虽然在技术上没有违反REST约束的情况,但传递所有值并不诉诸服务器默认值可能更好,因为这有助于保持向前兼容性。 默认值可以随时间变化,所以一般应该避免。

    然而,你的链接的例子并不是指不传递默认值,所以它不是一个“不完全表示”的好例子。 相反,链接不是客户端对服务器资源表示的一部分。 我想你会在这里混合使用另一个概念:只从服务器返回给客户端的属性。 这就是我在引发这篇文章的另一篇文章中谈到的。

    我所说的并不是不完整的表述; 这是一种不同的表现形式。 你真的在处理描述相同资源的两种不同媒体类型(即表示)。 一个来自客户端(我们将其称为application / vnd.example.api.client),另一个来自服务器(application / vnd.example.api.server)。 它们可能没有被明确标记,但至少隐含地发生了什么。 因此,由于它们是两种不同的媒体类型,它们表达关于同一资源的不同事物。

    既然你提到了HAL,考虑到客户端通常不会向服务器发送媒体类型application / hal + json的消息。 以HALTalk的rel注册为例。 预期的内容类型是application / json,而不是application / hal + json。 而且,如果你看一下示例文章,这里没有关于它的内容。 没有链接,没有嵌入对象等等。但是......如果你从这个POST返回的Location头返回的URL,假设你的客户端接受HAL通过JSON,返回一个类型为application / hal + json的响应(即,具有链接的用户)。 两种不同的媒体类型,相同资源的两种不同表示。

    因此,让我用Accept和Content-Type标题来修饰您的示例以说明我的观点。

    请求

    PUT /api/users/1 HTTP/1.1
    Content-Type: application/vnd.example.api.client+json
    
    {'username': 'joeydoey',
     'email': 'joey@doey.com'}
    

    响应

    200 OK
    Content-Type: application/hal+json;profile=application/vnd.example.api.server
    
    {'id': 1,
     'username': 'joeydoey',
     'email': 'joey@doey.com',
     'password_hash': '9039dmk38f84uf4029i339kf32f0932i',
     '_links': {'self': {'href': 'http://foo.bar.com/api/users/1'}}
    }
    

    大多数系统不会去详细描述它们的媒体类型。 通常它只是在一个更通用的类型框架(如应用程序/ JSON或只有一个自定义媒体类型)。 然而,这些都没有改变这一事实,尽管它是相同的基础资源,但这是两种不同的表示。 合理?


    PUT用于替换。 服务器可以修改/增加数据,但最终表示应该是有效负载的函数,而不是最终状态的函数。

    在你的例子中,密码哈希似乎不是服务器可以填写的东西,对吧? 在这种情况下,PUT应该导致错误。

    链接地址: http://www.djcxy.com/p/71259.html

    上一篇: Using the PUT method with incomplete representations

    下一篇: what are REST,RESTFul, SOA and microservices in simple terms?