<?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"
	>
<channel>
	<title>Comments for Coffee Powered</title>
	<atom:link href="http://www.coffeepowered.net/comments/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coffeepowered.net</link>
	<description>code and content</description>
	<pubDate>Tue, 06 Jan 2009 01:55:12 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
		<item>
		<title>Comment on Powerful, easy, DRY, multi-format REST APIs by Chris Heald</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/#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'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 "request attributes X, Y, and Z, get a hash back" on the model works great. What I'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'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'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'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'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&#8217;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&#8217;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>Comment on Powerful, easy, DRY, multi-format REST APIs by Matt Todd</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/#comment-36</link>
		<dc:creator>Matt Todd</dc:creator>
		<pubDate>Wed, 15 Oct 2008 01: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'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'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&#8217;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>
<pre><code>
def public_timeline_attributes
  self.attributes.reject do |attribute, value|
    not %w(id title created_at udated_at).include?(attribute.to_s)
  end
end
</code></pre>
<p>Of course, you&#8217;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>Comment on Powerful, easy, DRY, multi-format REST APIs by Chris Heald</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/#comment-35</link>
		<dc:creator>Chris Heald</dc:creator>
		<pubDate>Wed, 15 Oct 2008 01: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'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's displayed format in the model'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&#8217;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&#8217;s displayed format in the model&#8217;s hands violates MVC, and makes using it somewhat more brittle.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Powerful, easy, DRY, multi-format REST APIs by Matt Todd</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/#comment-34</link>
		<dc:creator>Matt Todd</dc:creator>
		<pubDate>Wed, 15 Oct 2008 00: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't really know what formatting options there are with WordPress.</description>
		<content:encoded><![CDATA[<p>Sorry for the lack of format&#8230; I don&#8217;t really know what formatting options there are with WordPress.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Powerful, easy, DRY, multi-format REST APIs by Matt Todd</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/#comment-33</link>
		<dc:creator>Matt Todd</dc:creator>
		<pubDate>Wed, 15 Oct 2008 00: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 &#60; 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'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>
<pre><code>
class Post &lt; ActiveRecord::Base
  def to_json
    self.attributes.to_json
  end
  def to_yaml
    self.attributes.to_yaml
  end
end
</code></pre>
<p>Of course, if you want, you define a method like so:</p>
<pre><code>
def public_attributes
  self.attributes.reject do |(attribute, value)|
    not %w(user_id, title, body, created_at).include?(attribute.to_s)
  end
end
</code></pre>
<p>Then you can have:</p>
<pre><code>
def to_json
  self.public_attributes.to_json
end
</code></pre>
<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&#8217;s attributes instead of a user ID. Whatever.</p>
<p>Much cleaner in my opinion.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Powerful, easy, DRY, multi-format REST APIs 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-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>Comment on Powerful, easy, DRY, multi-format REST APIs by Daniel T</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/#comment-22</link>
		<dc:creator>Daniel T</dc:creator>
		<pubDate>Fri, 03 Oct 2008 19: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'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 - I love this idea.  My only minor quibble is that it&#8217;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>
	<item>
		<title>Comment on Powerful, easy, DRY, multi-format REST APIs by เร็วส์ หกสิบหก » นั่งเทียนเขียนข่าว#12</title>
		<link>http://www.coffeepowered.net/2008/09/27/powerful-easy-dry-multi-format-rest-apis/#comment-20</link>
		<dc:creator>เร็วส์ หกสิบหก » นั่งเทียนเขียนข่าว#12</dc:creator>
		<pubDate>Thu, 02 Oct 2008 21:20:16 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=38#comment-20</guid>
		<description>[...] Coffee Powered » Powerful, easy, DRY, multi-format REST APIs [...]</description>
		<content:encoded><![CDATA[<p>[...] Coffee Powered » Powerful, easy, DRY, multi-format REST APIs [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Re: Simple RoR+MySQL optimization by Chris Heald</title>
		<link>http://www.coffeepowered.net/2008/09/30/re-simple-rormysql-optimization/#comment-19</link>
		<dc:creator>Chris Heald</dc:creator>
		<pubDate>Wed, 01 Oct 2008 22:33:04 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=58#comment-19</guid>
		<description>JGeiger:

Here's what I came up with. Not too surprising. :)

&lt;pre&gt;&lt;code&gt;
[chris@polaris benchmark]$ script/runner benchmark.rb
find_by_sql (10000x)
  2.430000   0.580000   3.010000 (  4.457347)
find_by_id (10000x)
  4.520000   0.490000   5.010000 (  6.620790)
find with conditions (10000x)
  3.740000   0.530000   4.270000 (  5.881615)
&lt;/code&gt;&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>JGeiger:</p>
<p>Here&#8217;s what I came up with. Not too surprising. <img src='http://www.coffeepowered.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre><code>
[chris@polaris benchmark]$ script/runner benchmark.rb
find_by_sql (10000x)
  2.430000   0.580000   3.010000 (  4.457347)
find_by_id (10000x)
  4.520000   0.490000   5.010000 (  6.620790)
find with conditions (10000x)
  3.740000   0.530000   4.270000 (  5.881615)
</code></pre>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Re: Simple RoR+MySQL optimization by JGeiger</title>
		<link>http://www.coffeepowered.net/2008/09/30/re-simple-rormysql-optimization/#comment-17</link>
		<dc:creator>JGeiger</dc:creator>
		<pubDate>Wed, 01 Oct 2008 14:54:59 +0000</pubDate>
		<guid isPermaLink="false">http://www.coffeepowered.net/?p=58#comment-17</guid>
		<description>I was wondering about what the difference would be for #1 if you replaced User.find_by_sql "select * from users where id = 123" or User.find_by_id 123 with
User.find(:all, :conditions =&#62; ["id = ?", 123])

It would seem that the find_by_id adds missing_method overhead, while the find(:all) should bypass that, and give you something a bit more similar to the find_by_sql.

Thanks.</description>
		<content:encoded><![CDATA[<p>I was wondering about what the difference would be for #1 if you replaced User.find_by_sql &#8220;select * from users where id = 123&#8243; or User.find_by_id 123 with<br />
User.find(:all, :conditions =&gt; ["id = ?", 123])</p>
<p>It would seem that the find_by_id adds missing_method overhead, while the find(:all) should bypass that, and give you something a bit more similar to the find_by_sql.</p>
<p>Thanks.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
