Rails:将 API 请求限制为 JSON 格式
Posted
技术标签:
【中文标题】Rails:将 API 请求限制为 JSON 格式【英文标题】:Rails: Restrict API requests to JSON format 【发布时间】:2013-01-17 19:30:58 【问题描述】:我想限制对所有 API 控制器的请求被重定向到 JSON 路径。我想使用重定向,因为 URL 也应该根据响应而改变。
一种选择是使用 before_filter
将请求重定向到相同的操作,但强制使用 JSON 格式。该示例尚未运行!
# base_controller.rb
class Api::V1::BaseController < InheritedResources::Base
before_filter :force_response_format
respond_to :json
def force_response_format
redirect_to, params[:format] = :json
end
end
另一种选择是在路由设置中限制格式。
# routes.rb
MyApp::Application.routes.draw do
namespace :api, defaults: format: 'json' do
namespace :v1 do
resources :posts
end
end
end
我希望所有请求都以 JSON 请求的形式结束:
http://localhost:3000/api/v1/posts
http://localhost:3000/api/v1/posts.html
http://localhost:3000/api/v1/posts.xml
http://localhost:3000/api/v1/posts.json
...
您会推荐哪种策略?
【问题讨论】:
【参考方案1】:第二个选项,使用路由格式。如果用户明确请求 XML 格式,他不应该收到 JSON 响应。他应该收到一条消息,指出此 URL 不响应 XML 格式或 404。
顺便说一句,我认为你应该做的所有事情都可以很容易地做出回应。
class FooController
respond_to :xml, :json
def show
@bar = Bar.find(params[:id])
respond_with(@bar)
end
end
【讨论】:
+1 表示评论的开头。根据我的经验,添加格式并不容易,尽管 Rails 很容易实现。 API 设计人员仍然需要考虑支持其他格式意味着什么,以及所有含义。【参考方案2】:在您的路由中设置默认值不会将所有请求都转换为 JSON 请求。
您想要确保呈现的内容是 JSON 响应
除了你需要这样做之外,你几乎在第一个选项中就有了它
before_filter :set_default_response_format
private
def set_default_response_format
request.format = :json
end
这将在您的 Base API 控制器下进行,因此当它到达您的实际操作时,格式将始终为 JSON。
【讨论】:
将request.format
设置为:json
解决了所有响应都返回JSON的问题。但它不会更改地址栏中的 URL。
如果你在做一个 API 为什么你需要在地址栏中写 URL?请注意,执行重定向会返回 300 状态,并且它可能不是最有效的,但请不要引用我的话。
这么说,你会建议在任何情况下将请求格式重写为 JSON 吗?另一种选择是返回一些 HTTP 状态作为 mathieugagne 和你提到的。
这些是您必须为您的 API 考虑的设计选项。您是只想接受/返回 JSON,还是愿意返回 XML 和其他格式...【参考方案3】:
如果你想返回 404,或者如果格式不是 :json
则引发 RouteNotFound 错误,我会添加这样的路由约束:
需要 JSON 格式:
# routes.rb
MyApp::Application.routes.draw do
namespace :api, constraints: format: 'json' do
namespace :v1 do
resources :posts
end
end
end
更多信息可以在这里找到: http://edgeguides.rubyonrails.org/routing.html#request-based-constraints
【讨论】:
我认为在这种情况下 406 是更准确的响应。知道为什么这种方法会返回 404 吗? @asymmetric 这是因为约束说“这个规则只匹配 json 请求”,所以任何非 json 请求都不会匹配,并且会一直到最后,除非你有一个特定的后续规则匹配非 json 请求并以另一个响应显式响应。以上是关于Rails:将 API 请求限制为 JSON 格式的主要内容,如果未能解决你的问题,请参考以下文章
Airbnb案例:Ruby on Rails YAML格式化字符串时导致的远程代码执行