3. REST, Resources, and Rails - 3.11 Different Representations of Resources

3.11 Different Representations of Resources

One of the precepts of REST is that the components in a REST-based system exchange representations of resources. The distinction between resources and their representations is vital.

As a client or consumer of REST services, you don’t actually retrieve a resource from a server; you retrieve representations of that resource. You also provide representations: A form submission, for example, sends the server a representation of a resource, together with a request—for example, PATCH—that this representation be used as the basis for updating the resource. Representations are the exchange currency of resource management.

3.11.1 The respond_to Method

The ability to return different representations in RESTful Rails practice is based on the respond_to method in the controller, which, allows you to return different responses depending on what the client wants. Moreover, when you create resource routes you automatically get URL recognition for URLs ending with a dot and a :format parameter.

For example, assume that you have resources :auctions in your routes file and some respond_to logic in the AuctionsController like:

def index
  @auctions = Auction.all 
  respond_to do |format|
    format.xml { render :xml => @auctions } 

which will let you to connect to this URL: /auctions.xml
The resource routing will ensure that the index action gets executed. It will also recognize the .xml at the end of the route and interact with respond_to accordingly, returning the XML representation.

There is also a more concise way of handling this now using the respond_with method.

class AuctionsController < ApplicationController 
  respond_to :html, :xml, :json
  def index
    @auctions = Auction.all

Here we’ve told our controller to respond to html,xml, and json so that each action will automatically return the appropriate content. When the request comes in, the responder would attempt to do the following given a .json extension on the URL:

  • Attempt to render the associated view with a .jsonextension.
  • If no view exists,call to_json on the object passed to responds_with.
  • If the object does not respond to to_json,call to_formaton it.

For nested and namespaced resources, simply pass all the objects to the respond_to method similar to the way you would generate a route.

respond_with(@user, :managed, @client)

3.11.2 Formatted Named Routes

Let’s say you want a link to the XML representation of a resource. You can achieve it by passing an extra argument to the RESTful named route:

link_to "XML version of this aution", auction_path(@auction, :xml)

# this will generate the following HTML:
# <a href="/auctions/1.xml">XML version of this auction</a>