情况:
通过POST
操作,用户可以根据给定的参数创建新资源。如果已存在从这些相同参数创建的资源,则返回现有资源。
如果用户知道资源ID(在创建时生成,并且实际上是随机的),则能够GET
此资源。我想为用户提供一种只知道创建参数并且不创建新资源来检查存在的方法。
问题:
在POST
正文中采取某种“只检查”属性来防止创建新资源会不会很好?
示例:
POST vehicle
{
colour: 'red',
wheels: 4
}
201: {
vehicleId: '314-159',
colour: 'red',
wheels: 4
}
GET vehicle/314-159
200: {
vehicleId: '314-159',
colour: 'red',
wheels: 4
}
POST vehicle
{
colour: 'red',
wheels: 4,
check: true
}
200: {
vehicleId: '314-159',
colour: 'red',
wheels: 4
}
POST vehicle
{
colour: 'blue',
wheels: 8,
check: true
}
404: Not Found
修改
大部分讨论都是围绕POST
操作是否应该是幂等的,虽然有效但不能解决我的问题。
我想为我的用户提供一种方法,仅根据用于创建资源的属性来验证资源的存在。
POST
方法的幂等性无关紧要。缺少此检查的是后续GET
个请求,这些请求将包含许多从未打算使用的资源,并且使查找有用信息变得更加困难。
包含“请勿创建”标记的POST
请求会满足此需求,但可能感觉 RESTful。
答案 0 :(得分:1)
如何实现幂等帖子?这样做可以避免“检查”身体参数。
答案 1 :(得分:0)
2个想法:
使用PUT和自然键
一个选项(不确定这是否适合你)是不在网址中使用一些数据库ID,但使用的东西更像是一个自然键。
因此,不要在某些集合上进行POST,而只需将项目放入:
1;1
2;1
3;2
4;2
PUT /vehicles/colour/blue/wheels/8
也可用于创作。你可以使用这样的标题来防止覆盖现有的值:
PUT
请不要将其放在客户端上进行此操作
如果用于创建项目的If-None-Match: *
与更新项目相同,该怎么办?或者,如果您在现有项目上调用POST
,它实际上并没有做任何事情。
也许客户不需要知道它是否只是创建了一个新项目,或者服务器是否已经拥有该项目。
请确保对于这两种情况,服务器的行为相同,你应该做得很好。
答案 2 :(得分:0)
如果用户知道资源ID(在创建时生成,并且实际上是随机的),则可以获取此资源。我想为用户提供一种只知道创建参数并且不创建新资源来检查存在的方法。
你会如何使用网站?
可能,对于一个表单,它将接受相同的创建参数作为输入。用户实际上执行搜索,这是一种语义安全的操作,因此表单可能会使用GET方法并将表单中的参数编码到查询字符串中。
端点在收到该请求后,可以将其重定向到适当的资源(如果已经存在)或其他资源以处理该情况时的情况。
采取某种"只是检查"是否可以轻松实现。 POST主体中的属性,以防止创建新资源?
当然 - 再次,您将如何在网站上执行此操作?表单将有一个额外的复选框,设置为正确的默认行为,但在提交表单之前,用户可以选择更改它。
因为切换复选框会将语义从安全操作更改为不安全操作,您可能希望在提交期间更改表单上的方法 - HTML本身不会这样做,但您可以这样做使用javascript aka code on demand。
使用POST进行safe操作并不理想,因为通用组件无法告诉操作是安全的。这意味着,如果响应丢失,他们无法自动重试请求,他们没有正确的默认缓存行为,等等。
答案 3 :(得分:0)
对于记录,选择的解决方案是在GET
方法上为特殊情况添加选项。
正如this answer中提到的那样,执行此类操作并不完全符合POST
方法的精神,并且它使呈现给用户的模型变得混乱。