处理POST和GET之间的RESTful表示结构差异

tar*_*rka 6 rest representation

我正在设计一个REST API,尽管在拖拽了一些最佳实践指南,但我找不到很多与处理从a返回的相同表示结构所需的表示结构之间的差异的最佳实践有关.POSTGET

GET对于虚拟user表示可能如下所示:

{
    "id": 1234,
    "created": "2012-04-23T18:25:43.511Z",
    "username": "johndoe@example.com",
    "name": "John Doe"
}
Run Code Online (Sandbox Code Playgroud)

但是,POST对于相同的虚拟user表示,不能指定某些属性(即idcreated):

{
    "username": "johndoe@example.com",
    "name": "John Doe"
}
Run Code Online (Sandbox Code Playgroud)

显然,这是一个过于简化的示例,但鉴于用户无法指定某些字段(并且可能并不总是明显哪些字段与应用的方法相关),最佳做法是为每个字段创建单独的表示或期望最完整的版本并在服务器上透明地处理数据差异?

尽管明显易于使用单一表示并处理差异服务器端,但我担心如果不清楚可以指定哪些值(或使用PUT例如更改),这对用户来说将是一种糟糕的体验.如果趋势是创建单独的表示,是否有应用于表示定义的命名约定?

例如,i_user对于传入用户和o_user传出用户.或user_fulluser_minuser.user等.

更新:我过于简化的示例可能没有正确说明问题.想象一下具有50个属性的表示(例如服务器表示及其所有监视属性--cpu,ram,temp,storage_drive_a,storage_drive_b,file_permission等).在这50个属性中,30个是只读属性,其中20个是值可以设定.

Ped*_*eck 2

首先,该POST方法的最终语义是由目标资源决定的,而不是像其他方法一样由 HTTP 协议决定,因此你的POST方法可以做任何你想做的事情,只要你正确地记录它,并且你不是复制已经通过其他方法标准化的功能。

因此,简而言之,采用不同的表示形式POSTGET方法并没有什么问题。

然而,在这种情况下寻求最佳实践是没有意义的,因为定义表示格式的是所使用的媒体类型,而不是方法,但互联网上大多数所谓的 REST API 使用通用媒体类型来表示所有事物和客户端都依赖 URI 语义来了解它们正在处理哪个资源,这根本不是 RESTful。基本上,当事情正确完成时,您正在寻求针对 REST 中并不真正存在的问题的最佳实践。

因此,为了回答你的问题,你可以对不同的媒体类型有不同的表示——比如完整的用户表示可能有一个媒体类型application/vnd.mycompany.user.full.v1+json,而简化的用户表示可能有一个媒体类型application/vnd.mycompany.user.min.v1+json——或者你可以有一个单一的表示像application/vnd.mycompany.user.v1+json这种媒体类型的文档和文档可能会详细说明某些属性如何存在或不存在,或者如果未提供,则可能具有默认值。您的 POST 方法将需要一种媒体类型才能工作,并且415 Unsupported Media Type如果客户端在标头中发送任何其他内容,则将进行响应Content-Type。以同样的方式,客户端可以选择它想要的标头表示形式Accept

正如您所看到的,当您真正使用 REST 而不仅仅是将其用作 HTTP API 的流行语时,您所要求的并不是问题。