在我的应用程序中有一个按钮(单击时)应该对所有实体(某种类型)应用一些变异。假设我的实体是"购买"点击"确认全部"按钮应该导致服务器/数据库设置"确认"所有"购买的领域" to" true"。
我有在服务器端执行此操作的代码。我的问题是:我应该为此操作使用的URI是什么?
POST似乎是错误的选择,因为此操作是幂等。因此,我留下了PUT。脑海中浮现出两个想法:
PUT /purchases?confirmed=true
PUT /purchaes/__all__?confirmed=true
有没有完善的惯例?
修改
还有第三种选择(Markus建议):
PUT /confirmations/?confirmed=true
当然,这可以起作用并且显然有其优点。我发现的(唯一)问题是确认不是我系统中的en实体。特别是没有GET /confirmations/some_id
URI可能令人困惑。
答案 0 :(得分:0)
首先,您应该用于此操作的URI是为该操作返回的购买集合的URI。 URI语义应该无关紧要。
其次,当我们说POST不是幂等的时,我们所说的是客户端不能默认假设该操作是幂等的。 POST方法的语义完全在你的控制之内,这就是为什么它们必须被记录下来,你不能依赖客户端事先知道它的作用,就像GET,PUT和DELETE一样。
简单来说,使用非幂等的PUT操作违反了HTTP方法语义,但是使用幂等的POST是可以的。
第三,你所做的是RPC,而不是REST。例如:
PUT /purchases?confirmed=true
您只是通过传递参数来调用方法。在REST中唯一有意义的方法是,如果您要创建或替换一组购买来替换confirmed=true
的子集,这将与您想要的完全相反。如果你想做类似的事情,你应该使用POST,而不是PUT。
很明显,您的确认是部分更新,因此您根本不应该使用PUT。作为一般规则,如果您尝试为GET,PUT,PATCH和DELETE定义与特定资源耦合的单独语义,那么您做错了。这些方法应该是通用的,并且对于一切都以完全相同的方式工作。如果您需要将某些URI和方法耦合到特定的资源状态转换,请使用POST。
我不知道API的细节,但看起来你正在使用查询字符串参数作为有效负载参数。这也不是一个好主意,因为你不能将URI视为原子标识符。
如果你的URI是原子的,你可以说这会返回所有未经证实的购买:
GET /purchases?confirmed=false
您可以将POST记录为批量执行部分更新的方法,更改已过滤的子集:
POST /purchases?confirmed=false
{ "confirmed": true }
如果你坚持使用PUT,你应该做这样的事情。如果您的URI低于该值,则通过使用AND减少所有购买来返回全局确认状态:
GET /purchases/confirmation
{ "confirmed": False }
然后你可以做类似的事情:
PUT /purchases/confirmation
{ "confirmed": true }