POST到控制器资源 - 控制者的ID应该是控制器URI的一部分还是POST参数?

时间:2012-03-13 13:47:55

标签: rest

在我的资源模型中,我有一个“订阅”资源。它经历了诸如“未订阅”的生命周期状态 - > “订阅待处理” - > “订阅” - > “取消订阅待定” - > “取消订阅”。

为了允许客户订阅或取消订阅订阅,我计划公开两个控制器资源(称为“sub”和“unsub”)以订阅/取消订阅订阅,每个接受POST请求将同步放置目标订阅资源进入适当的“挂起”状态,并异步执行其他工作以将订阅置于“已订阅”或“未订阅”状态。

在向“sub”或“unsub”发出POST请求时,我可以想到客户端指定目标订阅的几种方法。我可以将目标订阅ID放入URI中,如下所示:

/订阅/ {subscription_id} /子 或者可能 /分/ {subscription_id}

[注意:在URI中公开订阅ID不会给我的应用带来安全问题。]

或者,我可以将订阅ID设为POST参数:

/分

关于哪种方法更可取的想法?如果您更喜欢URI方法,您更喜欢哪种URI样式,为什么?

注意:已取消订阅的订阅随后可能会被重新订阅,因此“取消订阅”操作不等同于删除订阅资源。

2 个答案:

答案 0 :(得分:0)

我会将ID设为@ subscription的POST参数。

我没有单独/取消订阅资源,而是向/ subscription发送DELETE请求(以相同方式传入ID)。

我选择订阅而不是订阅者,因为订阅者对于您是创建/删除订阅还是实际订阅者/用户存在歧义。

编辑 - 后澄清。

REST使用动词GET,POST,PUT和DELETE。这里的GET对创建/更新没有意义。您不希望DELETE,因为您希望资源保持不变。所以我建议做一个POST来创建/启动一个订阅,一个PUT来修改/取消订阅一个订阅。这是对PUT动词的轻微误用,但我认为它比你的选择更适合你的情况。

答案 1 :(得分:0)

为了完整起见,我将根据进一步的研究和考虑给出另一个答案。

最终,如果您遵循HATEOAS原则,除了顶级URI之外的URI对客户端实际上是不透明的,因此从客户端的角度来看,控制者是否被识别出来并不重要。控制器的URI与否。从服务的角度来看,作为一个实际和美学的问题,将它从控制器的URI中删除会使它更短更简单,所以就是这样。

另一方面,在URI中暴露控制者将允许中间人(例如路由器或防火墙)更容易地检查并对该暴露的值采取行动,这在某些情况下可能是有用的。

对于我的项目,我最终决定在URI / subscription_tasks中公开一个控制器资源,接受包含动作(subscribe / unsubscribe)的POST和目标订阅ID作为POST有效负载中的表单参数。 POST返回一个subscription_task资源,可以通过GET轮询监视,直到任务完成。