Skip to content

Instantly share code, notes, and snippets.

@higgis
Created September 27, 2012 11:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save higgis/3793544 to your computer and use it in GitHub Desktop.
Save higgis/3793544 to your computer and use it in GitHub Desktop.
Rails: Default format using header-based content negotiation
class FoosController < ApplicationController
respond_to :atom, :api_v1
before_filter :set_default_format
def index
@foos = Foo.all
respond_to do |format|
format.xml { render :xml => @foos.to_xml }
format.api_v1 { render :json => @foos.to_json }
end
end
protected
# why do I need to do this? If I set :defaults => { :format => :xml }
# on my route then I only ever get that as the format even if
# the client sends an Accept header
def set_default_format
request.format = :xml if params[:format].nil? && request.headers["HTTP_ACCEPT"].nil?
end
end
Mime::Type.register "application/vnd.foos.api.v1+json", :api_v1
MyApp::Application.routes.draw do
get 'foos', :to => 'foos#index', :as 'foos'
end
@higgis
Copy link
Author

higgis commented Sep 27, 2012

I want to be able to have an API endpoint that defaults to serving XML unless the client sends an Accept header of application/vnd.foos.api.v1+json

The code above is the only way I've been able to make this work, but it feels like I'm doing something wrong and that I should be able to do it in the routes.rb file, but that makes the default format XML regardless of the the Accept header.

Anyone have a better way?

@urbanautomaton
Copy link

Unfortunately Rails' MIME negotiation prioritises the format parameter over everything else, so because it sets a parameter, the defaults hash in the routes file will always win out over an Accept header.

Given this, your existing solution is probably as good as any - the only other option I can think of is to start monkeypatching, which would be grim.

@urbanautomaton
Copy link

But hey, don't worry about the Accept header, it's a vestigial bit of nonsense that will soon be ignored completely in favour of that well-known part of the HTTP spec, "file extension": https://twitter.com/steveklabnik/status/243115995370233856

@higgis
Copy link
Author

higgis commented Sep 27, 2012

@urbanautomaton Thanks, at least I'm not going mental. Re: the "file extension" thing, is it 1998 all over again or something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment