【问题标题】:Rails: Restrict API requests to JSON formatRails:将 API 请求限制为 JSON 格式
【发布时间】: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
...

您会推荐哪种策略?

【问题讨论】:

    标签: ruby-on-rails json redirect restriction rails-api


    【解决方案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 请求并以另一个响应显式响应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多