I have a JSON
and XML
based API that needs to be page cached. I have setup my routes on the api to include the format as part of the URL, such that URL's like this work:
http://example.com/foo/1/bar/2/xml
http://example.com/foo/1/bar/2/json
The problem I am seeing is that in the server's public
folder, the files are being saved as xml.xml
and json.json
, and this causes cache misses the next time the URL is accessed.
Is there a way to either:
RAILS_ROOT/public/foo/1/bar/2/json
).html
for every call. (EX: RAILS_ROOT/public/foo/1/bar/2/json.html
)Either of these would cause my server to return the cached file instead of a miss. How can I do this?
EDIT:
Somebody asked for the relevant route:
scope '(foo/:foo_id)', :foo_id => /\d+/ do
get '/bar/:bar_id/:format' => 'bars#show', :bar_id => /\d+/, :format => /json|xml|html/
end
SOLUTION:
While I was looking for an official way to make this happen using the built in page caching support, I ended up just using an after filter and my own page cache method, as suggested by 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 ]
You can do that like this:
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
When http://example.com/foo/1/bar/2/json is accessed, it will write page to cache (RAILS_ROOT/public/foo/1/bar/2/json.html)
And if you get http://example.com/foo/1/bar/2/json again, you receive RAILS_ROOT/public/foo/1/bar/2/json.html, but your http server(Apache?) should know about content type of this files.
Otherwise content type will set to 'text/html'
UPDATE
To you .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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With