Respond to different formats in Rails controller

When you are writing an API for your application you might want to reuse your controllers to render JSONs or XMLs instead on top of your web views. Fortunately, rails has a nice feature called responds_to where you define the output of the action.

def index
  @links = Link.all
  respond_to do |format|
    format.html
    format.json do
      render json: { links: @links }
    end
    format.xml do
      render xml: { links: @links }.to_xml
    end
  end
end

The format object takes a block and executes it and if no block is provided it just follows the default path – it works similar to a switch case. So how does the controller decides which format it should serve?

It is determined by HTTP Accept header from the request and there is many ways how to set it up. There is several options for javascript with jquery:

$.getJSON("/api/search")
  .done(function(result) { console.log(result); });

$.ajax({ dataType: "json", url: "/api/search" })
  .done(function(result) { console.log(result); });

Also, you can specify the requested content just by entering an URL extension.

http://app.com/api/search.json
http://app.com/api/search.xml

Give it a try in your Chrome, it’s very useful for testing. There is one very useful Chrome extensions especially for API testing called Postman.

Postman example of HTTP accept header

You can use respond_to not just for API purposes but also for rendering different views based on the device the request came from. Checkout the documentation for more details and keep in mind that reusing your controllers might not be a perfect solution for your specific case.

Resources


Would you like to get the most interesting content about programming every Monday?
Sign up to Programming Digest and stay up to date!