2011-05-13 48 views
6

我有一个基于JSONXML的API需要页面缓存。我对API设置我的路线,包括格式作为URL的一部分,这样的URL像这样的工作:Rails页面缓存和自动扩展的问题

http://example.com/foo/1/bar/2/xml 
http://example.com/foo/1/bar/2/json 

我看到的问题是,在服务器的public文件夹,该文件被保存如xml.xmljson.json,这会在下次访问URL时导致缓存未命中。

有没有办法要么:

  1. 关闭自动扩展产生,因此它们被保存没有扩展名呢? (例如:RAILS_ROOT/public/foo/1/bar/2/json
  2. 为每个呼叫强制所有分机为.html。 (例如:RAILS_ROOT/public/foo/1/bar/2/json.html

其中任何一个都会导致我的服务器返回缓存文件而不是未命中。我怎样才能做到这一点?

编辑:
有人问了相关路线:

scope '(foo/:foo_id)', :foo_id => /\d+/ do 
    get '/bar/:bar_id/:format' => 'bars#show', :bar_id => /\d+/, :format => /json|xml|html/ 
end 



SOLUTION
虽然我一直在寻找一个正式的方式来做到这一点使用内置的网页缓存支持,我最终只使用后过滤器和我自己的页面缓存方法,正如Anton

# application_controller.rb 
def cache_api_page 
    if REDACTEDServer::Application.config.action_controller.perform_caching 
    self.class.cache_page(response.body, request.path, '') 
    puts "CACHED PATH: #{request.path}" 
    end 
end 

# bar_controller.rb 
after_filter :cache_api_page, :only => [ :show, :index ] 
+0

您是否尝试过API中的“正常”惯例,例如..bar/2.xml和../bar/2.json? – oma 2011-05-18 12:36:46

+0

这不是API设计,我需要使它向后兼容,所以我不能更改为.ext方法。恕我直言,但它使丑陋的网址。 – coneybeare 2011-05-18 16:22:47

+0

你可以发布你的路线样本吗? – 2011-05-20 03:27:18

回答

3

可以是这样做的:

class FooController < ApplicationController 

    after_filter(:only => :show, :if => Proc.new { |c| c.request.format.json? }) do |controller| 
    controller.class.cache_page(controller.response.body, controller.request.path, '.html') 
    end 

end 

http://example.com/foo/1/bar/2/json被访问,是将数据写入高速缓存(RAILS_ROOT /公/富/ 1 /酒吧/ 2/json.html)

如果您再次获得http://example.com/foo/1/bar/2/json,则会收到RAILS_ROOT/public/foo/1/bar/2/json.html,但您的http服务器(Apache?)应该知道这些文件的内容类型。

否则内容类型将设置为 'text/html的'

UPDATE

为了您的.htaccess

<FilesMatch "\/json$"> 
<IfModule mod_headers.c> 
    Header set Content-Type "text/json" 
</IfModule> 
</FilesMatch> 


<FilesMatch "\/xml$"> 
<IfModule mod_headers.c> 
    Header set Content-Type "text/xml" 
</IfModule> 
</FilesMatch> 
+0

这似乎可以工作,但需要在我的应用程序和方法中编写大量代码。我会继续给你答案,直到我看到还有什么其他东西。关于Apache,请求与上面列出的URL完全相同,因此Apache不知道它是xml或json文件,除非我提出请求.xml或.json扩展名。这就是为什么我需要这样做。 – coneybeare 2011-05-18 04:14:14

+0

你应该添加给你.htaccess ...看到更新 – Anton 2011-05-20 08:09:08

+0

你的更新不会在rails上工作,因为htaccess被rails,passenger apache设置忽略。你的初始答案仍然有效 – coneybeare 2011-05-21 01:33:39

0

在你的application.rb中配置块尝试添加:

config.action_controller.page_cache_extension = '.html' 

它应该忽略e从请求计算出来的xtension,并且总是使用这个。 你也可以尝试用空字符串来代替。

编辑:实际上这不会工作,因为这只会设置一个默认值。如果请求有扩展名(在你的情况下,从格式结束),它将被使用。

我建议改变:格式在你的路线到别的东西,那些铁轨不会给特别的意义,如:fmt。然后,rails不应将扩展名和默认值添加到“.html”。

EDIT2:如果你必须使用:格式可以猴补丁的Rails:

ActionController::Caching::Pages::ClassMethods 
    private 
    def page_cache_file(path) 
    name = (path.empty? || path == "/") ? "/index" : URI.unescape(path.chomp('/')) 
    name << page_cache_extension #unless (name.split('/').last || name).include? '.' 
    return name 
    end 
end 

通知我之前 '除非' 已经添加了注释符号。这是从我的第一个答案覆盖默认的部分。