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.html
format.xml { render :xml => @auctions }
end
end
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
respond_with(@auctions)
end
end
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
.json
extension. - If no view exists,call
to_json
on the object passed toresponds_with
. - If the object does not respond to
to_json
,callto_format
on 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>