Ruby on Rails - 在REST API中区分复数与单数资源

时间:2010-04-10 20:29:01

标签: ruby-on-rails ruby rest

在开始编写任何代码之前,我正在为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是有意义的。最好是避免这种头痛,或者你们中的一些人是否有同样的担忧,甚至更好 - 有一个有效的解决方案?

3 个答案:

答案 0 :(得分:17)

Rails(3)在单数与复数方面有很多约定。例如,模型类总是单数(Person),而相应的表总是复数(people)。 (例如,Person.all映射到select * from people。)

对于路线,有一个单一资源的概念以及一个复数资源。因此,如果您执行resource :account,则会为默认路径获取/account之类的路径,或者为表单编辑路径的/account/edit获取路径。 (请注意,Rails使用/accountPUT方法来实际更新帐户。/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