2013-02-02 14 views
23

我想限制将所有API控制器重定向到JSON路径的请求。我想使用重定向,因为URL也会根据响应而改变。
一种选择是使用before_filter,该请求将请求重定向到相同的动作但强制使用JSON格式。该示例尚未运行!Rails:将API请求限制为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 
... 

,你会推荐哪种策略?

回答

5

第二个选项,使用路线格式。如果用户明确请求XML格式,则不应收到JSON响应。他应该会收到一条消息,说这个URL不能回答XML格式,或者404。

顺便说一下,对于我认为应该做的所有事情做出回应将是相当容易的。

class FooController 
    respond_to :xml, :json 
    def show 
    @bar = Bar.find(params[:id]) 
    respond_with(@bar) 
    end 
end 
+0

+1的评论开始。根据我的经验,添加格式并不容易,尽管Rails使其易于实现。 API设计者仍然需要考虑支持其他格式的含义以及所有的影响。 –

19

在路由中设置默认值将不会将所有请求都转换为JSON请求。

你需要的是确保你在任何渲染是一个JSON响应

你几乎有它在第一个选项,除非你需要做到这一点

before_filter :set_default_response_format 

private 
    def set_default_response_format 
    request.format = :json 
    end 

这将大大在您的Base API控制器下,这样当它到达您的实际操作时,格式将始终为JSON。

+0

将'request.format'设置为':json'解决了所有响应返回JSON的问题。但它不会更改地址栏中的网址。 – JJD

+0

如果你正在做一个API,你为什么需要在地址栏中写入URL?请注意,做一个重定向会返回一个300的状态,它可能不是最有效的,请不要引用我的意思。 –

+0

这就是说,你会建议在任何情况下将请求格式重写为JSON吗?另一种选择是将一些HTTP状态返回为mathieugagne并且您提到。 – JJD

16

如果你想返回404,或提出一个RouteNotFound错误,如果格式不:json,我想补充一个路由约束是这样的:

要求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

+0

我认为在这种情况下406是更准确的回应。任何想法为什么这种方法返回404? – asymmetric