正如其他人(例如:here)我在努力解决这个问题时,GET和PUT的代表应该相同吗?
示例:
GET表示:
{
"id": "0815",
"name": "jdoe",
"emailAddress": "jd@example.com",
"displayName": "John Doe",
"active": true
}
PUT表示:
{
"emailAddress": "jd@example.com",
"displayName": "John Doe"
}
研究
我在REST question: PUT one representation, GET a different one?中读到,当我用PUT保存时,可以使用GET获得另一种媒体类型。
我在REST - put IDs in body or not?中读到,可以通过PUT省略id并使用GET获取id。
我在GET Representation != POST Representation中读到,可以通过PUT省略很多属性并使用GET获取它们。一个例子是JIRA REST API - api/2/myself。 GET返回空洞用户模型,PUT只保存3个属性。
这是好习惯吗?我也可以使用PATCH,例如GitHub REST API - users。如果PUT具有另一个较小的表示已足够,那么将PATCH添加到HTTP的原因是什么?
我在Best practice for partial updates in a RESTful service中读到的更多大REST API(例如:Google)使用PATCH或POST进行部分更新,而PUT仅用于完整/完整更新(例如: :Goolge - Updating an entity)。
答案 0 :(得分:4)
这个想法是服务器通常比用户有更多关于资源的信息,因此GET 可能返回的信息多于PUT所需的信息。服务器'拥有'有一些东西,因此客户端无法更新。这些可以由GET返回,而PUT表示不允许用户修改它们。
然而,这与PUT允许您部分更新资源的说法不同。当您输入文档时,您将更新该文档所涵盖的所有值 - 因此,应通过PUT发送的实际文档中不存在的“可选”值将从资源中删除</ em>。当您对该资源执行后续GET时,将不会显示可选值。
PATCH的语义应该略有不同 - 使用PATCH,客户端发送部分更新,以某种方式描述更改。然后,这些更改以某种方式应用于资源。通过PATCH发送的文档中未提及的资源部分将不加修改。
另请注意,PATCH明确定义为既不安全也不是幂等。虽然PUT是幂等的但不安全 - 重复的相同请求将导致相同的变化。使用PATCH,某些更改可能是累积的(例如,向列表添加值),因此重复的请求可能会导致资源的状态不同。
答案 1 :(得分:1)
我在努力解决这个完全相同的问题。感谢您对它的研究以及对它的清晰表达。我认为这里存在的问题是,服务器/后端确定/创建了 的数据,REST尚未真正解决最佳实践问题。例如:
在每个简单的REST示例中,您看到它与您的POST / PUT之间的内容之间似乎相当对称。例如,REST会让你相信,如果你对集合(或资源)进行GET,然后POST(或PUT)那个响应主体就应该没有变化,但这只是不现实的考虑上述例子。所以从本质上讲,你的GET响应成为实际POST / PUT主体的超集。
我用这个术语作为对两者之间关系不对称的头部点头,就是说我的GET返回集合/资源的Readonly表示,而不是POST / PUT主体接受的。这很适合代码,您可以从对象继承Readonly
表示,以使用您的服务器/后端负责创建/管理的属性来扩充它。例如,这里有两个TypeScript接口,显示用户可以PUT(IPet
)的数据与服务器为GET(IReadonlyPet
)响应的数据
interface IPet {
name: string, // The user can change the pet's name
}
interface IReadonlyPet extends IPet {
id: number, // The user should not be able to change the pet's id
}
我不知道我是否强迫用户在GET请求之后进行POST / PUT时剥离id
之类的内容,因为这需要很多数据转换努力询问您的API消费者。我可以看到两个有效且相反的论点:
id
并且你只是默默地忽略它可能会让他们错误地了解集合/资源的实际状态。id
,然后执行POST / PUT,你就会忽略id
属性。如果我必须选择一个,我可能会选择第二个选项,因为我认为它可以为您的API消费者提供更简单,更对称的体验,因为他们可以完成一个完整的GET,POST / PUT GET响应,并再次获得GET以获得相同的原始响应。此外,您的API使用者可能真的抱怨超出定义架构的数据的实现行为,因为您已经脱离了标准化的常规路径。