Ruby on rails Rails API设计

Ruby on rails Rails API设计,ruby-on-rails,ruby-on-rails-3,design-patterns,Ruby On Rails,Ruby On Rails 3,Design Patterns,我有一个主要基于REST的rails站点,我想添加JSON API支持 对于干净的代码库,我应该在现有控制器中添加此支持,还是创建只处理此API方法的新控制器,然后将所有公共代码移动到模型/助手?Rails控制器生成器默认实现JSON响应 例如,如果您有此方法: class UsersController < ApplicationController def index @users = User.all end end 现在,您的应用程序将响应http://somea

我有一个主要基于REST的rails站点,我想添加JSON API支持


对于干净的代码库,我应该在现有控制器中添加此支持,还是创建只处理此API方法的新控制器,然后将所有公共代码移动到模型/助手?

Rails控制器生成器默认实现JSON响应

例如,如果您有此方法:

class UsersController < ApplicationController
  def index
    @users = User.all
  end
end
现在,您的应用程序将响应
http://someapp.com/users.xml


自定义json 您可能不想在json中输出表的所有字段。为此,请注意。它允许您使用生成器样式的DSL创建JSON结构

jbuilder自述文件中的一个示例

Jbuilder.encode do |json|
  json.content format_content(@message.content)
  json.(@message, :created_at, :updated_at)

  json.author do
    json.name @message.creator.name.familiar
    json.email_address @message.creator.email_address_with_name
    json.url url_for(@message.creator, format: :json)
  end

  if current_user.admin?
    json.visitors calculate_visitors(@message)
  end

  json.comments @message.comments, :content, :created_at

  json.attachments @message.attachments do |attachment|
    json.filename attachment.filename
    json.url url_for(attachment)
  end
end
生成以下输出:

{ 
  "content": "<p>This is <i>serious</i> monkey business",
  "created_at": "2011-10-29T20:45:28-05:00",
  "updated_at": "2011-10-29T20:45:28-05:00",

  "author": {
    "name": "David H.",
    "email_address": "'David Heinemeier Hansson' <david@heinemeierhansson.com>",
    "url": "http://example.com/users/1-david.json"
  },

  "visitors": 15,

  "comments": [
    { "content": "Hello everyone!", "created_at": "2011-10-29T20:45:28-05:00" },
    { "content": "To you my good sir!", "created_at": "2011-10-29T20:47:28-05:00" }
  ],

  "attachments": [
    { "filename": "forecast.xls", "url": "http://example.com/downloads/forecast.xls" },
    { "filename": "presentation.pdf", "url": "http://example.com/downloads/presentation.pdf" }
  ]
}
{
“内容”:“这是严重的猴子生意”,
“创建时间”:“2011-10-29T20:45:28-05:00”,
更新日期:“2011-10-29T20:45:28-05:00”,
“作者”:{
“姓名”:“David H.”,
“电子邮件地址”:“David Heinemeier Hansson”,
“url”:”http://example.com/users/1-david.json"
},
“访客”:15,
“评论”:[
{“内容”:“大家好!”,“创建于”:“2011-10-29T20:45:28-05:00”},
{“内容”:“祝你我的好先生!”,“创建于”:“2011-10-29T20:47:28-05:00”}
],
“附件”:[
{“filename”:“forecast.xls”,“url”:http://example.com/downloads/forecast.xls" },
{“filename”:“presentation.pdf”,“url”:http://example.com/downloads/presentation.pdf" }
]
}

我使用了两种技术:在相同的控制器中编写API逻辑和为API请求创建单独的控制器

如果它只是一个API,一个只供您使用的小应用程序,那么使用rails提供的默认控制器模型关系。代码将非常干净。您的路由文件也将是干净的

如果你有一个网站,你想建立一个API,单独做。我已经在现有控制器旁边构建了一个,代码太混乱了。我多次重构代码,但我仍然不喜欢(这也是个人品味的问题)

另一种解决方案是使用前缀创建控制器。例如:
ApiUsersController
。这将使您的
routes.rb
文件看起来很难看,因为您必须手动指定路由以匹配相应的控制器方法

我的工作解决方案是将所有API逻辑移动到API命名空间下的单独控制器中。名称空间还允许您进行API版本控制。例如,您的路线将是:

GET /api/v1/users.json
POST /api/v1/users.json
然后,在将来,您可以创建另一个API版本,比如说
v2
,而不会破坏使用旧版本API的现有应用程序

您可以在此处找到有关名称空间的更多信息:


关于REST完整API版本控制的精彩教程:

到目前为止,这是我喜欢的答案,非常有用,但实际上并没有回答这个问题。。。克里斯蒂安·伊莱亚(Cristian Ilea)有最合适的一行。
format.js{render:json=>@users}
应该是
format.json{render:json=>@users}
{ 
  "content": "<p>This is <i>serious</i> monkey business",
  "created_at": "2011-10-29T20:45:28-05:00",
  "updated_at": "2011-10-29T20:45:28-05:00",

  "author": {
    "name": "David H.",
    "email_address": "'David Heinemeier Hansson' <david@heinemeierhansson.com>",
    "url": "http://example.com/users/1-david.json"
  },

  "visitors": 15,

  "comments": [
    { "content": "Hello everyone!", "created_at": "2011-10-29T20:45:28-05:00" },
    { "content": "To you my good sir!", "created_at": "2011-10-29T20:47:28-05:00" }
  ],

  "attachments": [
    { "filename": "forecast.xls", "url": "http://example.com/downloads/forecast.xls" },
    { "filename": "presentation.pdf", "url": "http://example.com/downloads/presentation.pdf" }
  ]
}
GET /api/v1/users.json
POST /api/v1/users.json