REST Url 结构 - 资源 ID 可以位于控制器之前吗?
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 向我建议存在一个类型为 speed 且标识符为 ESX-121 的资源,但事实并非如此,操作是在汽车上进行的。
对于此类情况,您如何构建 URL 以及相关的控制器和操作? 您认为这是一个可以接受的解决方案,还是有更好的方法来构建它?
The standard template for ASP.NET MVC (and MVC in general) seems to be {controller}/{action}/{id}, however, on a project i'm currently working on i'm not sure if that is an appropriate structure. If for example I had an application that controlled a car, to me it would make more sense to me to have the structure below:
{car-rego}/{controller}/{action}/{data etc}
This makes sense to me because the car (identified by registration plate) is the resource we are performing operations on and the logical separation of functionality is seperated into the controller and action. This would result in URL's such as:
/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
If this followed the default pattern it would be something like below:
/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
To me the first option makes it much more sense as far as readable URL's go and the resource identifier is in a constant logical place. For example /Speed/Set/ESX-121/100 suggests to me that there is a resouce of type speed with an identifier of ESX-121 which is not really the case, the operation is on the car.
How do you go about structuring URL's and the related controllers and actions for cases such as this? Do you think this is an acceptable solution, or is there a better way for this to be structured?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从“哲学”的角度来看,这是一个大问题。
您似乎对几乎所有事情都使用 GET 请求,例如设置速度。
REST 背后的想法是,访问 ESX-121 资源可以为您提供其当前状态的表示,在您的情况下,它的速度、方向、是否打开等。
在其 URL 上发布汽车的某些表示将有效地更改其当前状态状态。 (例如,如果您使用 XML 进行表示,您可以通过发布
来更改其速度。在 ASP.net MVC 下,您可以为此发布一个表单。
您想要做的是应用 SOAP 服务建模方式(面向操作(或动词)到 REST 服务,这并不是真正的想法。
“获得”REST 做事方式可能很困难,并且它可能与您使用 SOAP 服务所做的一切背道而驰。记住这些原则很重要,
理论上,您的 URL 描述了一个资源,并且唯一可用的操作是通过 GET(读取)、POST(创建)、PUT(创建或更新)、DELETE(删除)执行的。
编辑:感谢 marxidad 纠正我每个动词应该映射到的内容。
There is a big problem, from a "philosophical" point of view.
You seem to be using GET requests for pretty much everything, such as setting speed.
The idea behind REST is that access to the ESX-121 resource gives you a representation of its current state, in your case its speed, its direction, if it's on etc.
POSTing some representation of the car at its URL will effectively change its current state. (If you are using XML for representation for example, you could post
to change its speed. Under ASP.net MVC you would POST a form for that.
What you are trying to do is to apply a SOAP service way of modeling (geared towards operations, or verbs) to a REST service, which is not really the idea.
It can be difficult to "get" the REST way of doing things, and it can go against everything you have been doing i you were using SOAP services, but it is important to keep those principles in mind.
In theory, you URL describes a resource, and the only operations available are carried out through GET (read), POST (create), PUT (create or update), DELETE (delete).
EDIT: Thanks to marxidad for correcting me on what each verb should map to.
除了上面帖子中指出的评论之外,我认为稍微改变一下结构是完全可以的。 (但不要像上面指出的那样使用 GET 来更新数据)
以 CMS 为例,您经常会看到以下结构:
{controller}/{id}/{action}
或
pages/about_the_company
(显示操作是默认操作)pages/about_the_company/edit
(GET 将显示编辑页面,而 POST 将执行更新)当然,在 CMS 中,控制器将默认为
pages
,因此网址将甚至更短。Besides from the comments pointed out in the post above, I think it is perfectly ok to change the structure around a bit. (But not use GET for updating data as pointed out above)
Take for example a CMS, you'll often see the following structure:
{controller}/{id}/{action}
or
pages/about_the_company
(the display action is the default action)pages/about_the_company/edit
(GET will display the edit page, while POST will perform an update)Of course in a CMS the controller would be defaulted to
pages
so the url's would be even shorter.REST 并不是要拥有干净的 URI,而是要为 HTTP 方法 GET、POST、PUT 和 DELETE 附加正确的语义。
GET 应该仅用于安全幂等操作,POST 应该用于创建或处理,PUT 应该用于更新现有资源,DELETE 应该用于(嗯)删除资源。
您可以使用带有大量“?”和“&”的丑陋 URI。 参数,同时如果您愿意,仍然可以开始 RESTful。
现在关于您的 URI,虽然第二个选项可能看起来不错,但它是使用非英语语言编写“简单英语”的一种方法。 首先,这听起来可能是个好主意,但使 URI 可读的主要思想是客户端可以使用它们并发现新功能。 这就是为什么将站点/应用程序的树结构保留在 URI 中始终是一个更好的主意。
有关该主题的更多信息,请参阅 Jacob Nielsen 的关于 URL 作为 UI 的 Alertbox。
REST is not about having clean URIs, it is about having the correct semantic attached to HTTP methods GET, POST, PUT and DELETE.
GET should only be for safe idempotent operations, POST should be for creation or processing, PUT should be for updating an existing resource and DELETE to (hmm) delete a resource.
You can use ugly URIs with lots of "? and &" parameters while still begin RESTful if you want.
Now about your URIs, while the second option may look fine, it is a way to write "plain english" using a language that is not english. It may sound a good idea in the first place, but the main idea behind making URIs readable is that the client can play with them and discover new features. That's why it is always a better idea to keep the tree structure of your site/application in your URIs.
See Jacob Nielsen's Alertbox about URL as UI for more information on the topic.
如果您定义任何类型的 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 了解更多信息。
If you define any kind of URI naming structure like "{car-rego}/{controller}/{action}/{data etc}" then your API is not REST. It is simply RPC. You cannot define URIs or URI naming conventions as part of a REST API - it directly violates one of the constraints of RESTful architecture.
See http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven for more information.