在开始编写任何代码之前,我正在为REST API构建URL。 Rails REST魔术很棒,但我对URL的格式有点困扰,例如:
http://myproject/projects/5
其中Project是我的资源,5是project_id。我认为如果用户想要检索他们的所有项目,那么相应的HTTP GET http://myproject/projects
是有意义的。但是,如果他们希望检索单一资源(例如项目)的信息,那么http://myproject/project/5
vs http://myproject/projects/5
是有意义的。最好是避免这种头痛,或者你们中的一些人是否有同样的担忧,甚至更好 - 有一个有效的解决方案?
答案 0 :(得分:17)
Rails(3)在单数与复数方面有很多约定。例如,模型类总是单数(Person
),而相应的表总是复数(people
)。 (例如,Person.all
映射到select * from people
。)
对于路线,有一个单一资源的概念以及一个复数资源。因此,如果您执行resource :account
,则会为默认路径获取/account
之类的路径,或者为表单编辑路径的/account/edit
获取路径。 (请注意,Rails使用/account
和PUT
方法来实际更新帐户。/account/edit
是一个用于编辑帐户的表单,这是与帐户本身不同的资源。)如果您但是,如果你resources :people
,/people
和/people/1
这样的路径就行了/people/1/edit
。路径本身表明是否只能存在给定类型资源的一个实例,或者是否可以存在由某种类型的标识符区分的多个实例。
答案 1 :(得分:3)
我同意,顺其自然。考虑URL如何形成层次结构。
您网站的根目录是您开始访问任何内容的地方。
/ projects /将其缩小到只有项目,而不是其他任何东西。从项目中你可以做很多事情,/ list,/ index /,/ export等... / id进一步限制了事情。
在每个/更窄的范围内,我认为这是有道理的。
进一步的编程都是关于任意规则的。索引从1开始对0,依此类推。任何使用您网址的人都会在短时间内解决问题。
答案 2 :(得分:1)
有些情况下,资源的单一路径是有用的。如果您的资源ID是非数字用户定义的名称,则可以进行路由冲突。例如:
/ applications / new - >创建一个新的应用程序或显示名为new的用户应用程序?
在这种情况下,您可以选择限制用户输入以避免冲突,或者,这可以通过覆盖默认的Rails 3行为来解决:
class ActionDispatch::Routing::Mapper
module Resources
RESOURCE_OPTIONS << :singular_resource
class Resource
def member_scope
@options[:singular_resource] ? "#{singular}/:id" : "#{path}/:id"
end
def nested_scope
@options[:singular_resource] ? "#{singular}/:#{singular}_id" : "#{path}/:#{singular}_id"
end
end
end
end
然后指定新资源路径时:
resources :applications, :singular_resource => true
将生成路线:
GET /applications
GET /applications/new
POST /applications
GET /application/:id
GET /application/:id/edit
PUT /application/:id
DELETE /application/:id