REST URL结构 - 资源ID可以在控制器之前运行吗?

时间:2009-03-30 02:52:38

标签: asp.net-mvc model-view-controller url rest friendly-url

ASP.NET MVC(以及一般的MVC)的标准模板似乎是 {controller} / {action} / {id} ,但是,在我正在进行的项目上我不确定这是否是一个合适的结构。例如,如果我有一个控制汽车的应用程序,对我来说,拥有以下结构对我来说更有意义:

  {car-rego}/{controller}/{action}/{data etc}

这对我来说很有意义,因为汽车(由登记牌识别)是我们正在进行操作的资源,并且功能的逻辑分离被分离到控制器和动作中。这将产生URL,例如:

/ESX-121/Power/On
/ESX-121/Speed/Set/100
/ESX-121/Speed/Current -- get the current speed (could be /ESX-121/Speed also)
/ESX-121/Turn/Left
/ESX-121/Speed/Set/90
/ESX-121/Power/Off

如果这遵循默认模式,它将如下所示:

/Power/On/ESX-121
/Speed/Set/ESX-121/100
/Speed/Current/ESX-121 -- get the current speed (could be /Speed/ESX-121 also)
/Turn/Left/ESX-121
/Speed/Set/ESX-121/90
/Power/Off/ESX-121

对我而言,就可读URL而言,第一个选项更有意义,资源标识符位于一个恒定的逻辑位置。例如 / Speed / Set / ESX-121/100 向我建议,存在类型速度的资源,其标识符为ESX-121,实际情况并非如此,操作在车上

如何构建URL以及相关控制器和操作以解决此类问题?您认为这是一个可接受的解决方案,还是有更好的方法来构建它?

4 个答案:

答案 0 :(得分:5)

从“哲学”的角度来看,存在一个很大的问题。

您似乎正在使用GET请求几乎所有内容,例如设置速度。 REST背后的想法是,访问ESX-121资源可以让您表示其当前状态,在您的情况下,它的速度,方向,如果它等等。

在其URL上发布汽车的某些表示将有效地改变其当前状态。 (例如,如果您使用XML进行表示,则可以发布

<car><id>ESX-121</id><speed>100</speed><car>

改变它的速度。在ASP.net MVC下,您可以为此发布表单。

您要做的是将SOAP服务建模方式(面向操作或动词)应用于REST服务,这不是真正的想法。

可能很难“获得”REST的处理方式,并且它可能违背您在使用SOAP服务时所做的一切,但重要的是要牢记这些原则。

理论上,URL描述了一个资源,唯一可用的操作是通过GET(读取),POST(创建),PUT(创建或更新),DELETE(删除)来执行的。

编辑:感谢marxidad纠正每个动词应该映射的内容。

答案 1 :(得分:3)

除了上面帖子中指出的评论之外,我认为将结构改变一下是完全可以的。 (但不要使用GET来更新数据,如上所述)

以CMS为例,您经常会看到以下结构:

{controller}/{id}/{action}

pages/about_the_company(显示操作是默认操作)
pages/about_the_company/edit(GET将显示编辑页面,而POST将执行更新)

当然,在CMS中,控制器默认为pages,因此网址会更短。

答案 2 :(得分:1)

REST不是要有干净的URI,而是要将正确的语义附加到HTTP方法GET,POST,PUT和DELETE。

GET应仅用于安全的幂等操作,POST应该用于创建或处理,PUT应该用于更新现有资源,DELETE应该用于(hmm)删除资源。

你可以使用丑陋的URI,其中有很多“?和&amp;”参数虽然仍然可以开始RESTful。

现在关于你的URI,虽然第二个选项可能看起来不错,但是这是一种使用非英语语言编写“普通英语”的方法。首先,它可能听起来不错,但使URI可读的主要思想是客户端可以使用它们并发现新功能。这就是为什么将您的站点/应用程序的树结构保留在URI中总是更好的主意。

有关该主题的更多信息,请参阅Jacob Nielsen's Alertbox about URL as UI

答案 3 :(得分:0)

如果您定义任何类型的URI命名结构,例如“{car-rego} / {controller} / {action} / {data etc}”,那么您的API不是REST。它只是RPC。您不能将URI或URI命名约定定义为REST API的一部分 - 它直接违反了RESTful架构的一个约束。

有关详细信息,请参阅http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven