<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Powerful, easy, DRY, multi-format REST APIs</title>
	<atom:link href="http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/</link>
	<description>code and content</description>
	<lastBuildDate>Thu, 02 Feb 2012 08:43:52 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
	<item>
		<title>By: Eric Pugh</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-193</link>
		<dc:creator>Eric Pugh</dc:creator>
		<pubDate>Tue, 21 Apr 2009 11:40:59 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-193</guid>
		<description>It took me two hours after reading your article to get JSONP to work, I was missing adding an explicit :callback parameter! 
 
format.json { render :json =&gt; @artists.to_json(), :callback =&gt; params[:callback] } </description>
		<content:encoded><![CDATA[<p>It took me two hours after reading your article to get JSONP to work, I was missing adding an explicit :callback parameter!</p>
<p>format.json { render :json =&gt; @artists.to_json(), :callback =&gt; params[:callback] }</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Coffee Powered &#187; Things to do when upgrading to Rails 2.3</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-162</link>
		<dc:creator>Coffee Powered &#187; Things to do when upgrading to Rails 2.3</dc:creator>
		<pubDate>Tue, 17 Mar 2009 00:55:52 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-162</guid>
		<description>[...] means that the faster_xml_simple monkeypatch is no longer needed. I don&#8217;t think we&#8217;re doing much else with XML on blippr, but [...]</description>
		<content:encoded><![CDATA[<p>[...] means that the faster_xml_simple monkeypatch is no longer needed. I don&#8217;t think we&#8217;re doing much else with XML on blippr, but [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alexwebmaster</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-130</link>
		<dc:creator>Alexwebmaster</dc:creator>
		<pubDate>Tue, 03 Mar 2009 05:47:55 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-130</guid>
		<description>Hello webmaster  
I would like to share with you a link to your site  
write me here preonrelt@mail.ru </description>
		<content:encoded><![CDATA[<p>Hello webmaster </p>
<p>I would like to share with you a link to your site </p>
<p>write me here <a href="mailto:preonrelt@mail.ru">preonrelt@mail.ru</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chris Heald</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-37</link>
		<dc:creator>Chris Heald</dc:creator>
		<pubDate>Wed, 15 Oct 2008 02:01:32 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-37</guid>
		<description>The abstracted method that lets me pass a list of desired attributes and get back a hash is the method I&#039;d originally gone with in a recent app...until I realized that when I wanted to construct complex views of the data, I was passing in massive multi-level hashes that defined a hierarchy of desired attributes across a series of models that were effectively doing the same thing that an XML builder did for me.

In simple cases, some kind of &quot;request attributes X, Y, and Z, get a hash back&quot; on the model works great. What I&#039;ve found is that by allowing each view to decide what data is relevant, I can expose more or less data for each API call, with the intent of reducing the number of followup calls that a developer would have to make in order to get all the data they want, without necessarily bloating the response results by throwing in everything and the kitchen sink.

If I have topics -&gt; posts -&gt; users, and I request a list of a user&#039;s posts in a serialized format, I may want something like:

&lt;pre&gt;&lt;code&gt;user {
  id
  name
  picture
  posts {
    post body
    post date
    post link
    owning thread {
      title
      link
    }
  }
}&lt;/code&gt;&lt;/pre&gt;

However, if I want to get a list of posts in a thread, the view may need to be something like:

&lt;pre&gt;&lt;code&gt;
thread {
  title
  link
  posts {
    post body
    post date
    user {
      id
      name
      picture
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

Two very different views. To do those in the model, I&#039;d need something like

&lt;pre&gt;&lt;code&gt;
@user.for_serialization(:id, :name, :picture, [:posts =&gt; {:body, :date, :link, [:thread =&gt; {:title, :link}]}]).to_json

@thread.for_serialization(:title, :link, [:posts =&gt; {:body, :date, [:users =&gt; {:id, :name, :picture}]}]).to_json
&lt;code&gt;&lt;/pre&gt;

Oof. Starting to get a little heavy, and that&#039;s both assuming a for_serialization that accepts nested attributes like that, and a relatively simple example.

If you want to get more complex and start including data that&#039;s not necessarily available to the model, like, say, links generated via your routing, then you have to start passing procs into your for_serialization. It becomes a giant unholy mess.

I did initially go the route of an ActiveRecord extension which provided super-customizable serialization calls, with nested associations and procs and the like, and it was just incredibly unwieldy to use in practicality.</description>
		<content:encoded><![CDATA[<p>The abstracted method that lets me pass a list of desired attributes and get back a hash is the method I&#8217;d originally gone with in a recent app&#8230;until I realized that when I wanted to construct complex views of the data, I was passing in massive multi-level hashes that defined a hierarchy of desired attributes across a series of models that were effectively doing the same thing that an XML builder did for me.</p>
<p>In simple cases, some kind of &#8220;request attributes X, Y, and Z, get a hash back&#8221; on the model works great. What I&#8217;ve found is that by allowing each view to decide what data is relevant, I can expose more or less data for each API call, with the intent of reducing the number of followup calls that a developer would have to make in order to get all the data they want, without necessarily bloating the response results by throwing in everything and the kitchen sink.</p>
<p>If I have topics -> posts -> users, and I request a list of a user&#8217;s posts in a serialized format, I may want something like:</p>
<pre><code>user {
  id
  name
  picture
  posts {
    post body
    post date
    post link
    owning thread {
      title
      link
    }
  }
}</code></pre>
<p>However, if I want to get a list of posts in a thread, the view may need to be something like:</p>
<pre><code>
thread {
  title
  link
  posts {
    post body
    post date
    user {
      id
      name
      picture
    }
  }
}
</code></pre>
<p>Two very different views. To do those in the model, I&#8217;d need something like</p>
<pre><code>
@user.for_serialization(:id, :name, :picture, [:posts => {:body, :date, :link, [:thread => {:title, :link}]}]).to_json

@thread.for_serialization(:title, :link, [:posts => {:body, :date, [:users => {:id, :name, :picture}]}]).to_json
</code><code></code></pre>
<p>Oof. Starting to get a little heavy, and that's both assuming a for_serialization that accepts nested attributes like that, and a relatively simple example.</p>
<p>If you want to get more complex and start including data that's not necessarily available to the model, like, say, links generated via your routing, then you have to start passing procs into your for_serialization. It becomes a giant unholy mess.</p>
<p>I did initially go the route of an ActiveRecord extension which provided super-customizable serialization calls, with nested associations and procs and the like, and it was just incredibly unwieldy to use in practicality.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Todd</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-36</link>
		<dc:creator>Matt Todd</dc:creator>
		<pubDate>Tue, 14 Oct 2008 19:16:03 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-36</guid>
		<description>But here you do end up with misrepresentation and a bit more explicit definition where it&#039;s not exactly necessary. So you want multiple attribute profiles (for a lack of a better term)? Just have different methods that respond with hashes with the right data... 
 
&lt;pre&gt;&lt;code&gt; 
def public_timeline_attributes 
  self.attributes.reject do &#124;attribute, value&#124; 
    not %w(id title created_at udated_at).include?(attribute.to_s) 
  end 
end 
&lt;/code&gt;&lt;/pre&gt; 
 
Of course, you&#039;d abstract it out to something where you can just name which parameters to expose, and have it always respond with a Hash. This way calling #to_json or #to_yaml on it always gets what you want. 
 
There may be better solutions but I think putting attribute publicity is something that the model should concern itself with, especially when you can keep the view very simple and clean (and not requiring transforming to XML then back again). It makes changes in the model site-wide and maintenance of those views not necessary. </description>
		<content:encoded><![CDATA[<p>But here you do end up with misrepresentation and a bit more explicit definition where it&#039;s not exactly necessary. So you want multiple attribute profiles (for a lack of a better term)? Just have different methods that respond with hashes with the right data&#8230;</p>
<p>&lt;pre&gt;&lt;code&gt;</p>
<p>def public_timeline_attributes</p>
<p>  self.attributes.reject do |attribute, value|</p>
<p>    not %w(id title created_at udated_at).include?(attribute.to_s)</p>
<p>  end</p>
<p>end</p>
<p>&lt;/code&gt;&lt;/pre&gt;</p>
<p>Of course, you&#039;d abstract it out to something where you can just name which parameters to expose, and have it always respond with a Hash. This way calling #to_json or #to_yaml on it always gets what you want.</p>
<p>There may be better solutions but I think putting attribute publicity is something that the model should concern itself with, especially when you can keep the view very simple and clean (and not requiring transforming to XML then back again). It makes changes in the model site-wide and maintenance of those views not necessary.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chris Heald</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-35</link>
		<dc:creator>Chris Heald</dc:creator>
		<pubDate>Tue, 14 Oct 2008 19:06:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-35</guid>
		<description>My issue with tying to_json/to_yaml to the model is that it presumes that I will always want the same representation of the model everywhere I want to express that model in a serialized format. It&#039;s a fairly brittle solution, though certainly a quick and easy one. I found that often times, I needed to have a lot of control over the data that was being exposed in these formats, and doing so required jumping through all kinds of hoops, either in the controller or in the model, when what I was really doing was trying to express a specific view for the model. 
 
In the MVC architecture, the model should simply present its data to the view, and the view should decide how to present that data to the user; placing ownership of the model&#039;s displayed format in the model&#039;s hands violates MVC, and makes using it somewhat more brittle. </description>
		<content:encoded><![CDATA[<p>My issue with tying to_json/to_yaml to the model is that it presumes that I will always want the same representation of the model everywhere I want to express that model in a serialized format. It&#039;s a fairly brittle solution, though certainly a quick and easy one. I found that often times, I needed to have a lot of control over the data that was being exposed in these formats, and doing so required jumping through all kinds of hoops, either in the controller or in the model, when what I was really doing was trying to express a specific view for the model.</p>
<p>In the MVC architecture, the model should simply present its data to the view, and the view should decide how to present that data to the user; placing ownership of the model&#039;s displayed format in the model&#039;s hands violates MVC, and makes using it somewhat more brittle.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Todd</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-34</link>
		<dc:creator>Matt Todd</dc:creator>
		<pubDate>Tue, 14 Oct 2008 18:53:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-34</guid>
		<description>Sorry for the lack of format... I don&#039;t really know what formatting options there are with WordPress. </description>
		<content:encoded><![CDATA[<p>Sorry for the lack of format&#8230; I don&#039;t really know what formatting options there are with WordPress.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Todd</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-33</link>
		<dc:creator>Matt Todd</dc:creator>
		<pubDate>Tue, 14 Oct 2008 18:40:53 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-33</guid>
		<description>I really think this is overcomplicating a simple problem. 
 
For JSON and YAML, all you need to do is define a method on the model you want to expose, like so: 
 
&lt;pre&gt;&lt;code&gt; 
class Post &lt; ActiveRecord::Base 
  def to_json 
    self.attributes.to_json 
  end 
  def to_yaml 
    self.attributes.to_yaml 
  end 
end 
&lt;/code&gt;&lt;/pre&gt; 
 
Of course, if you want, you define a method like so: 
 
&lt;pre&gt;&lt;code&gt; 
def public_attributes 
  self.attributes.reject do &#124;(attribute, value)&#124; 
    not %w(user_id, title, body, created_at).include?(attribute.to_s) 
  end 
end 
&lt;/code&gt;&lt;/pre&gt; 
 
Then you can have: 
 
&lt;pre&gt;&lt;code&gt; 
def to_json 
  self.public_attributes.to_json 
end 
&lt;/code&gt;&lt;/pre&gt; 
 
That means no code in the controller... much cleaner. 
 
Also provides you a little hook to even add computed attributes if you like, or include even a user&#039;s attributes instead of a user ID. Whatever. 
 
Much cleaner in my opinion. </description>
		<content:encoded><![CDATA[<p>I really think this is overcomplicating a simple problem.</p>
<p>For JSON and YAML, all you need to do is define a method on the model you want to expose, like so:</p>
<p>&lt;pre&gt;&lt;code&gt;</p>
<p>class Post &lt; ActiveRecord::Base</p>
<p>  def to_json</p>
<p>    self.attributes.to_json</p>
<p>  end</p>
<p>  def to_yaml</p>
<p>    self.attributes.to_yaml</p>
<p>  end</p>
<p>end</p>
<p>&lt;/code&gt;&lt;/pre&gt;</p>
<p>Of course, if you want, you define a method like so:</p>
<p>&lt;pre&gt;&lt;code&gt;</p>
<p>def public_attributes</p>
<p>  self.attributes.reject do |(attribute, value)|</p>
<p>    not %w(user_id, title, body, created_at).include?(attribute.to_s)</p>
<p>  end</p>
<p>end</p>
<p>&lt;/code&gt;&lt;/pre&gt;</p>
<p>Then you can have:</p>
<p>&lt;pre&gt;&lt;code&gt;</p>
<p>def to_json</p>
<p>  self.public_attributes.to_json</p>
<p>end</p>
<p>&lt;/code&gt;&lt;/pre&gt;</p>
<p>That means no code in the controller&#8230; much cleaner.</p>
<p>Also provides you a little hook to even add computed attributes if you like, or include even a user&#039;s attributes instead of a user ID. Whatever.</p>
<p>Much cleaner in my opinion.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: vBharat.com &#187; Powerful, easy, DRY, multi-format REST APIs</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-31</link>
		<dc:creator>vBharat.com &#187; Powerful, easy, DRY, multi-format REST APIs</dc:creator>
		<pubDate>Tue, 14 Oct 2008 01:15:06 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-31</guid>
		<description>&lt;strong&gt;From vBharat.com &#187; Powerful, easy, DRY, multi-format REST APIs...&lt;/strong&gt;

Rails’ baked-in REST support is great. Build your app right, and you can expose a programmatic interface to your users for free....</description>
		<content:encoded><![CDATA[<p><strong>From vBharat.com &#187; Powerful, easy, DRY, multi-format REST APIs&#8230;</strong></p>
<p>Rails’ baked-in REST support is great. Build your app right, and you can expose a programmatic interface to your users for free&#8230;.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel T</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/comment-page-1/#comment-22</link>
		<dc:creator>Daniel T</dc:creator>
		<pubDate>Fri, 03 Oct 2008 13:46:01 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-22</guid>
		<description>Excellent - I love this idea.  My only minor quibble is that it&#039;s a little confusing having an xml builder in the JSON renderer.  I would prefer an abstract structure builder (index.structure.builder) that would be semantically clearer. </description>
		<content:encoded><![CDATA[<p>Excellent &#8211; I love this idea.  My only minor quibble is that it&#039;s a little confusing having an xml builder in the JSON renderer.  I would prefer an abstract structure builder (index.structure.builder) that would be semantically clearer.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

