<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Api-Development on Damian Galarza | Software Engineering &amp; AI Consulting</title><link>https://www.damiangalarza.com/tags/api-development/</link><description>Recent posts from Damian Galarza | Software Engineering &amp; AI Consulting</description><generator>Hugo</generator><language>en-us</language><managingEditor>Damian Galarza</managingEditor><atom:link href="https://www.damiangalarza.com/tags/api-development/feed.xml" rel="self" type="application/rss+xml"/><item><title>Take Control of Your HTTP Caching in Rails</title><link>https://www.damiangalarza.com/posts/2015-01-26-take-control-of-your-http-caching-in-rails/</link><pubDate>Mon, 26 Jan 2015 00:00:00 -0500</pubDate><author>Damian Galarza</author><guid>https://www.damiangalarza.com/posts/2015-01-26-take-control-of-your-http-caching-in-rails/</guid><description>Get more control over HTTP caching in Rails.</description><content:encoded><![CDATA[<p>This post was originally published on the <a href="https://thoughtbot.com/blog/take-control-of-your-http-caching-in-rails">thoughtbot blog</a>.</p>
<p>The Rails <code>fresh_when</code> method is a powerful tool for conditionally caching resources via HTTP. However there are some pitfalls. For one, <code>fresh_when</code> only supports the default render flow in a controller; if a client&rsquo;s cache is not fresh, it will just render the related view. We cannot utilize things like <code>render json:</code>.</p>
<p>Fortunately, Rails provides us with more tools to work with HTTP conditional caching. Some of the basics behind HTTP conditional caching are assumed in this post. If you haven&rsquo;t already, or you just need a refresher take a look at <a href="/posts/2014-11-25-introduction-to-conditional-http-caching-with-rails/">Introduction to Conditional HTTP Caching with Rails</a>.</p>
<p>Let&rsquo;s work with a simple Rails blog application which renders posts as JSON.</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#6c7086;font-style:italic"># app/controllers/posts_controller.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">class</span> <span style="color:#f9e2af">PostsController</span> <span style="color:#89dceb;font-weight:bold">&lt;</span> <span style="color:#f9e2af">ApplicationController</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">def</span> <span style="color:#89b4fa">show</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f5e0dc">@post</span> <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#f9e2af">Post</span><span style="color:#89dceb;font-weight:bold">.</span>find(params<span style="color:#89dceb;font-weight:bold">[</span><span style="color:#a6e3a1">:id</span><span style="color:#89dceb;font-weight:bold">]</span>)
</span></span><span style="display:flex;"><span>    render <span style="color:#a6e3a1">json</span>: <span style="color:#f5e0dc">@post</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#6c7086;font-style:italic"># config/routes</span>
</span></span><span style="display:flex;"><span><span style="color:#f9e2af">Rails</span><span style="color:#89dceb;font-weight:bold">.</span>application<span style="color:#89dceb;font-weight:bold">.</span>routes<span style="color:#89dceb;font-weight:bold">.</span>draw <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>  resources <span style="color:#a6e3a1">:posts</span>, <span style="color:#a6e3a1">only</span>: <span style="color:#89dceb;font-weight:bold">[</span><span style="color:#a6e3a1">:show</span><span style="color:#89dceb;font-weight:bold">]</span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>What if we wanted to allow the client to conditionally cache this content? Rails provides us with the <a href="http://api.rubyonrails.org/classes/ActionController/ConditionalGet.html#method-i-stale-3F"><code>stale?</code></a> method which takes a resource and checks to see if the ETag provided by the client via the <code>If-None-Matches</code> header matches the one which represents the resource&rsquo;s current state. The <code>stale?</code> method can also work with the <code>If-Modified-Since</code> header. It will check if the resource&rsquo;s <code>updated_at</code> has been modified since the timestamp provided by <code>If-Modified-Since</code>.  To utilize this, we just need to wrap our <code>render</code> call with a call to <code>stale?</code>.</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#cba6f7">class</span> <span style="color:#f9e2af">PostsController</span> <span style="color:#89dceb;font-weight:bold">&lt;</span> <span style="color:#f9e2af">ApplicationController</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">def</span> <span style="color:#89b4fa">show</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f5e0dc">@post</span> <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#f9e2af">Post</span><span style="color:#89dceb;font-weight:bold">.</span>find(params<span style="color:#89dceb;font-weight:bold">[</span><span style="color:#a6e3a1">:id</span><span style="color:#89dceb;font-weight:bold">]</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#cba6f7">if</span> stale?(<span style="color:#f5e0dc">@post</span>)
</span></span><span style="display:flex;"><span>      render <span style="color:#a6e3a1">json</span>: <span style="color:#f5e0dc">@post</span>
</span></span><span style="display:flex;"><span>    <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>If we make a request to the individual post we&rsquo;ll get something similar to the following response:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl -i http://localhost:3000/posts/1
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#cba6f7">HTTP</span><span style="color:#89dceb;font-weight:bold">/</span><span style="color:#fab387">1.1</span> <span style="color:#fab387">200</span> <span style="color:#fab387">OK</span>
</span></span><span style="display:flex;"><span>Etag<span style="color:#89dceb;font-weight:bold">:</span> &#34;f049a9825a0239db3d01ead65a5ea522&#34;
</span></span><span style="display:flex;"><span>Last-Modified<span style="color:#89dceb;font-weight:bold">:</span> Tue, 02 Dec 2014 18:31:42 GMT
</span></span><span style="display:flex;"><span>Content-Type<span style="color:#89dceb;font-weight:bold">:</span> application/json; charset=utf-8
</span></span><span style="display:flex;"><span>Cache-Control<span style="color:#89dceb;font-weight:bold">:</span> max-age=0, private, must-revalidate
</span></span><span style="display:flex;"><span>Server<span style="color:#89dceb;font-weight:bold">:</span> WEBrick/1.3.1 (Ruby/2.1.5/2014-11-13)
</span></span><span style="display:flex;"><span>Date<span style="color:#89dceb;font-weight:bold">:</span> Tue, 02 Dec 2014 18:31:48 GMT
</span></span><span style="display:flex;"><span>Content-Length<span style="color:#89dceb;font-weight:bold">:</span> 93
</span></span><span style="display:flex;"><span>Connection<span style="color:#89dceb;font-weight:bold">:</span> Keep-Alive
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>{<span style="color:#cba6f7">&#34;post&#34;</span>:{<span style="color:#cba6f7">&#34;title&#34;</span>:<span style="color:#a6e3a1">&#34;Blog post 0&#34;</span>,<span style="color:#cba6f7">&#34;body&#34;</span>:<span style="color:#a6e3a1">&#34;lorem ipsum&#34;</span>,<span style="color:#cba6f7">&#34;created_at&#34;</span>:<span style="color:#a6e3a1">&#34;2014-11-12T15:30:34.025Z&#34;</span>}}<span style="color:#f38ba8">%</span>
</span></span></code></pre></div><p>If we take a look at our Rails server log, we&rsquo;ll see something similar to the following:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-plaintext" data-lang="plaintext"><span style="display:flex;"><span>Started GET &#34;/posts/1&#34; for 127.0.0.1 at 2014-12-02 13:38:18 -0500
</span></span><span style="display:flex;"><span>Processing by PostsController#show as */*
</span></span><span style="display:flex;"><span>  Parameters: {&#34;id&#34;=&gt;&#34;1&#34;}
</span></span><span style="display:flex;"><span>  Post Load (0.2ms)  SELECT  &#34;posts&#34;.* FROM &#34;posts&#34;  WHERE &#34;posts&#34;.&#34;id&#34; = $1
</span></span><span style="display:flex;"><span>LIMIT 1  [[&#34;id&#34;, 1]]
</span></span><span style="display:flex;"><span>Completed 200 OK in 1ms (Views: 0.3ms | ActiveRecord: 0.2ms)
</span></span></code></pre></div><p>Now if we make a request with the <code>If-None-Match</code> header set to the ETag that the server provided us with earlier:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>curl -i -H <span style="color:#a6e3a1">&#39;If-None-Match: &#34;f049a9825a0239db3d01ead65a5ea522&#34;&#39;</span> http://localhost:3000/posts/1
</span></span></code></pre></div><p>We&rsquo;ll now receive a 304 Not Modified status for our request.</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#cba6f7">HTTP</span><span style="color:#89dceb;font-weight:bold">/</span><span style="color:#fab387">1.1</span> <span style="color:#fab387">304</span> <span style="color:#fab387">Not Modified</span>
</span></span><span style="display:flex;"><span>Etag<span style="color:#89dceb;font-weight:bold">:</span> &#34;f049a9825a0239db3d01ead65a5ea522&#34;
</span></span><span style="display:flex;"><span>Last-Modified<span style="color:#89dceb;font-weight:bold">:</span> Tue, 02 Dec 2014 18:31:42 GMT
</span></span><span style="display:flex;"><span>Cache-Control<span style="color:#89dceb;font-weight:bold">:</span> max-age=0, private, must-revalidate
</span></span><span style="display:flex;"><span>Server<span style="color:#89dceb;font-weight:bold">:</span> WEBrick/1.3.1 (Ruby/2.1.5/2014-11-13)
</span></span><span style="display:flex;"><span>Date<span style="color:#89dceb;font-weight:bold">:</span> Tue, 02 Dec 2014 18:32:53 GMT
</span></span><span style="display:flex;"><span>Connection<span style="color:#89dceb;font-weight:bold">:</span> Keep-Alive
</span></span></code></pre></div><p>If we take a look at our Rails log we&rsquo;ll notice that the server skipped over the process of rendering the JSON all together:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-plaintext" data-lang="plaintext"><span style="display:flex;"><span>Started GET &#34;/posts/1&#34; for 127.0.0.1 at 2014-12-02 13:38:55 -0500
</span></span><span style="display:flex;"><span>Processing by PostsController#show as */*
</span></span><span style="display:flex;"><span>  Parameters: {&#34;id&#34;=&gt;&#34;1&#34;}
</span></span><span style="display:flex;"><span>  Post Load (0.2ms)  SELECT  &#34;posts&#34;.* FROM &#34;posts&#34;  WHERE &#34;posts&#34;.&#34;id&#34; = $1
</span></span><span style="display:flex;"><span>LIMIT 1  [[&#34;id&#34;, 1]]
</span></span><span style="display:flex;"><span>Completed 304 Not Modified in 1ms (ActiveRecord: 0.2ms)
</span></span></code></pre></div><p>In this trivial example our gain is not huge. However with more complicated JSON objects this can be a very useful. A common example is a larger JSON response built via <code>ActiveModel::Serializers</code>. Combined with key-based caching in ActiveModel::Serializers this can be a powerful tool. We can cache individual items with <a href="http://blog.remarkablelabs.com/2012/12/russian-doll-caching-cache-digests-rails-4-countdown-to-2013">russian doll caching</a>, and then cache the entire response via HTTP caching.</p>
<h2 id="further-reading">Further Reading</h2>
<ul>
<li><a href="https://thoughtbot.com/blog/fast-json-apis-in-rails-with-key-based-caches-and">Fast JSON APIs in Rails with Key-Based Caches and ActiveModel::Serializers</a></li>
<li><a href="https://thoughtbot.com/blog/how-to-evaluate-your-rails-json-api-for-performance-improvements">How to Evaluate Your Rails JSON API for Performance Improvements</a></li>
</ul>
]]></content:encoded></item><item><title>Scaling JSON APIs in Rails using ActiveModel::Serializers, Key-Based Caching, and Rack::Cache</title><link>https://www.damiangalarza.com/posts/scaling-json-apis-in-rails/</link><pubDate>Sun, 03 Nov 2013 00:00:00 +0000</pubDate><author>Damian Galarza</author><guid>https://www.damiangalarza.com/posts/scaling-json-apis-in-rails/</guid><description>Learn proven strategies for scaling JSON APIs in Rails applications. Performance optimization techniques using ActiveModel::Serializers, key-based caching, and Rack::Cache with real-world examples.</description><content:encoded><![CDATA[<p>This summer at Canvas I worked on a project which was a very dynamic and front-end heavy. In order to build this we architected it such a manner that the front-end would communicate with our servers through a JSON API. The API was responsbile for feeding the data used by the Javascript application. With this in mind we wanted the API to respond as fast as possible and be able to handle scale.</p>
<h1 id="organizing-our-api">Organizing our API</h1>
<p>Building our API we set out to achieve a few goals:</p>
<ul>
<li>Make the API flexibile and decoupled from the front-end implementation</li>
<li>Leverage HTTP caching whereever possible</li>
<li>Ensure it could handle high scale</li>
</ul>
<p>Making the API decoupled from it&rsquo;s front-end implmentation ensured that any design or data usage changes made would not require a change in 2 areas of our code base, the JavaScript application and the Rails application / API.</p>
<p>Leveraging HTTP caching gave us 2 gains. The first is we wanted to leverage an individual user&rsquo;s caching in their browser, reducing the amount of data we needed to send back to the user. The 2nd gain, which in my opinion was the bigger gain was the ability to add a caching layer in front of the entire response body through Rack::Cache.</p>
<h2 id="activemodelserializers">ActiveModel::Serializers</h2>
<p>(ActiveModel::Serializers)[https://github.com/rails-api/active_model_serializers] is a great library for encapsulating object serialization for JSON APIs in Rails. It provides a great Object Oriented approach to serialization. If you haven&rsquo;t seen it before I highly recommend checking it out. Furthermore, it implements caching through Rails.cache to provide the ability to cache serialization of objects using (key based expiration)[http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works]. This provided us with some very nice, quick and easy caching of our serialized data. Thoughtbot has a great (article on ActiveModel::Serailziers and caching)[http://robots.thoughtbot.com/post/50091183897/fast-json-apis-in-rails-with-key-based-caches-and] so I&rsquo;m not going to get into the details of it.</p>
<p>With this caching we were able to get a great method of caching our serialization. However we wanted more. Our models have a lot of associations which can be re-used through Russian doll caching. We implemented (this pull request)[https://github.com/rails-api/active_model_serializers/pull/307] in or serializers in order to benefit from side-effect free russian doll caching. With this in mind we could reuse caches just as easily across requests when possbile.</p>
<h2 id="rackcache">Rack::Cache</h2>
<p>Leveraging Rack::Cache in front of the API was one of the biggest wins for us. Rails has Rack::Cache active in production mode by default. However if you aren&rsquo;t using HTTP caching properly you won&rsquo;t see the benfits. There are many articles on the details of the various HTTP caching mechanisms that can be used. From <code>cache-control</code> headers, to <code>etags</code> and <code>last-modified</code> time stamps. Before we jump into the details let me explain why Rack::Cache was so useful.</p>
<p>When leveraging russian doll caching for our serialization we were able to get very fast serialization for our objects. However this typically lead to lots of memcached requests for fetcihng the individual pieces of the cache. This was not optimal. Our architecture benefited from the fact that one parent object could be used to determine the freshess of a cache. Think of the classic todo list example. Where individual todos in a list are cached as part of the entire todo list. If any individual todo-item in the list expires, then the list itself is expired. So, if we were using ActiveModel::Serialziers with caching, it would hit a cache for each item in the todo list.</p>
<h2 id="outline">Outline</h2>
<ul>
<li>Weeks JSON public to all users</li>
<li>Picks public because it&rsquo;s route is built from user ID.</li>
<li>ActiveModel::Serializers</li>
<li>Rack::Cache</li>
</ul>
]]></content:encoded></item><item><title>NewRelic RPM with ActionController::Metal</title><link>https://www.damiangalarza.com/posts/2012-09-05-newrelic-rpm-with-actioncontroller-metal/</link><pubDate>Wed, 05 Sep 2012 00:00:00 +0000</pubDate><author>Damian Galarza</author><guid>https://www.damiangalarza.com/posts/2012-09-05-newrelic-rpm-with-actioncontroller-metal/</guid><content:encoded><![CDATA[<p>As part of our work with the <a href="http://www.qfive.com">QFive</a> API for internal consumption we&rsquo;ve built it out using Rails&rsquo; ActionController::Metal.
We quickly realized that incoming requests to the API were not being tracked by NewRelic and looked for a way to resolve this. A quick google search will yield <a href="https://newrelic.com/docs/ruby/adding-instrumentation-to-actioncontroller-metal">this documentation from New Relic</a>
which includes the following example:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#cba6f7">class</span> <span style="color:#f9e2af">SteelController</span> <span style="color:#89dceb;font-weight:bold">&lt;</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Metal</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rendering</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">def</span> <span style="color:#89b4fa">show</span>
</span></span><span style="display:flex;"><span>    render <span style="color:#a6e3a1">:text</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> <span style="color:#a6e3a1">&#34;Here is some text&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">include</span> <span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">NewRelic</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Agent</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ControllerInstrumentation</span>
</span></span><span style="display:flex;"><span>  add_transaction_tracer <span style="color:#a6e3a1">:show</span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>While this works, the problem remains that now you will need to add a transaction tracer for each and every controller action you add.</p>
<p>With this in mind I went in search of a better solution which could streamline the solution. Digging around the NewRelic RPM gem internals I was able to find the &lsquo;magic&rsquo; behind the way New Relic integrates into requests. Within <code>lib/new_relic/agent/instrumentation/rails3/action_controller.rb</code> you can find the following:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#f9e2af">DependencyDetection</span><span style="color:#89dceb;font-weight:bold">.</span>defer <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f5e0dc">@name</span> <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#a6e3a1">:rails3_controller</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  depends_on <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>    defined?(<span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rails</span>) <span style="color:#89dceb;font-weight:bold">&amp;&amp;</span> <span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rails</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">VERSION</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">MAJOR</span><span style="color:#89dceb;font-weight:bold">.</span>to_i <span style="color:#89dceb;font-weight:bold">==</span> <span style="color:#fab387">3</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  depends_on <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>    defined?(<span style="color:#f9e2af">ActionController</span>) <span style="color:#89dceb;font-weight:bold">&amp;&amp;</span> defined?(<span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Base</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  executes <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f9e2af">NewRelic</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Agent</span><span style="color:#89dceb;font-weight:bold">.</span>logger<span style="color:#89dceb;font-weight:bold">.</span>debug <span style="color:#a6e3a1">&#39;Installing Rails 3 Controller instrumentation&#39;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  executes <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>    <span style="color:#cba6f7">class</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Base</span>
</span></span><span style="display:flex;"><span>      <span style="color:#cba6f7">include</span> <span style="color:#f9e2af">NewRelic</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Agent</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ControllerInstrumentation</span>
</span></span><span style="display:flex;"><span>      <span style="color:#cba6f7">include</span> <span style="color:#f9e2af">NewRelic</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Agent</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rails3</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ActionController</span>
</span></span><span style="display:flex;"><span>    <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>  <span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>Which handles including the various instrumentation tools for ActionController. With this in mind we can follow the same logic in our API BaseController:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#89dceb">require</span> <span style="color:#a6e3a1">&#39;new_relic/agent/instrumentation/controller_instrumentation&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#89dceb">require</span> <span style="color:#a6e3a1">&#39;new_relic/agent/instrumentation/rails3/action_controller&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#89dceb">require</span> <span style="color:#a6e3a1">&#39;new_relic/agent/instrumentation/rails3/errors&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">class</span> <span style="color:#f9e2af">Api</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">V1</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">BaseController</span> <span style="color:#89dceb;font-weight:bold">&lt;</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Metal</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rescue</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#6c7086;font-style:italic"># ...</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#6c7086;font-style:italic"># In order to enable NewRelic RPM monitoring in the API we&#39;ll need to include it</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">NewRelic</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Agent</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ControllerInstrumentation</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">NewRelic</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Agent</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rails3</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ActionController</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">NewRelic</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Agent</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rails3</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Errors</span>
</span></span><span style="display:flex;"><span>		
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div>]]></content:encoded></item><item><title>AssetPath with ActionController::Metal</title><link>https://www.damiangalarza.com/posts/2012-08-13-assetpath-with-actioncontroller-metal/</link><pubDate>Mon, 13 Aug 2012 02:26:53 -0400</pubDate><author>Damian Galarza</author><guid>https://www.damiangalarza.com/posts/2012-08-13-assetpath-with-actioncontroller-metal/</guid><content:encoded><![CDATA[<p>At QFive we&rsquo;re building an API to serve our iOS application and throughout the site for ajax requests. Since our API only serves JSON we could slim down our controllers being used for the API to speed up requests as much as possible. In order to achieve this we&rsquo;ve built a base controller for our API which inherits from ActionController::Metal instead of ActionController::Base. I was originally introduced to this idea in the book &ldquo;Crafting Rails Applications&rdquo; by Jose Valim.</p>
<p>One issue we&rsquo;ve run into we&rsquo;ve run into is related to the asset pipeline and serving assets from a custom asset host.</p>
<p>For example:</p>
<p><em>config/environments/production.rb</em></p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#f9e2af">Example</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Application</span><span style="color:#89dceb;font-weight:bold">.</span>configure <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>	config<span style="color:#89dceb;font-weight:bold">.</span>action_controller<span style="color:#89dceb;font-weight:bold">.</span>asset_host <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#a6e3a1">&#34;//static.example/com&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>Typically the usage behind this in a rails application is masked, whenever you use <em>image_tag</em> the image will be routed to the asset host on its own behind the scenes. However since we&rsquo;re inheriting from ActionController::Base there is some work to be done. We&rsquo;ll need to include a couple of modules and ensure that the load hooks are loaded in our base controller, something that happens behind the scenes when inheriting from ActionController::Base.</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#cba6f7">class</span> <span style="color:#f9e2af">Api</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">V1</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">BaseController</span> <span style="color:#89dceb;font-weight:bold">&lt;</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Metal</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">AbstractController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">AssetPaths</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Redirecting</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rendering</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Caching</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Renderers</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">All</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ConditionalGet</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ParamsWrapper</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">MimeResponds</span>
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#f9e2af">ActiveSupport</span><span style="color:#89dceb;font-weight:bold">.</span>run_load_hooks(<span style="color:#a6e3a1">:action_controller</span>, <span style="color:#89dceb">self</span>)
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>Of course, depending on what your application is using your mileage may vary. Our actual API BaseController looks something more like:</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#cba6f7">class</span> <span style="color:#f9e2af">Api</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">V1</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">BaseController</span> <span style="color:#89dceb;font-weight:bold">&lt;</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Metal</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">AbstractController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">AssetPaths</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Helpers</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Redirecting</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rendering</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Caching</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Renderers</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">All</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ConditionalGet</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">ParamsWrapper</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">MimeResponds</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">RequestForgeryProtection</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">AbstractController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Callbacks</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Instrumentation</span>
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">ActionController</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Rescue</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#f9e2af">Rails</span><span style="color:#89dceb;font-weight:bold">.</span>application<span style="color:#89dceb;font-weight:bold">.</span>routes<span style="color:#89dceb;font-weight:bold">.</span>default_url_options <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#f9e2af">ActionMailer</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">Base</span><span style="color:#89dceb;font-weight:bold">.</span>default_url_options
</span></span><span style="display:flex;"><span>	<span style="color:#cba6f7">include</span> <span style="color:#f9e2af">Rails</span><span style="color:#89dceb;font-weight:bold">.</span>application<span style="color:#89dceb;font-weight:bold">.</span>routes<span style="color:#89dceb;font-weight:bold">.</span>url_helpers
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	append_view_path <span style="color:#a6e3a1">&#34;</span><span style="color:#a6e3a1">#{</span><span style="color:#f9e2af">Rails</span><span style="color:#89dceb;font-weight:bold">.</span>root<span style="color:#a6e3a1">}</span><span style="color:#a6e3a1">/app/views&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	protect_from_forgery
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#f9e2af">ActiveSupport</span><span style="color:#89dceb;font-weight:bold">.</span>run_load_hooks(<span style="color:#a6e3a1">:action_controller</span>, <span style="color:#89dceb">self</span>)
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>Be sure to check out the rails ActionController::Base to see what else is included by default and tweak as you see fit.</p>
]]></content:encoded></item><item><title>Simple Sinatra Service Proxy</title><link>https://www.damiangalarza.com/posts/2012-04-02-simple-sinatra-service-proxy/</link><pubDate>Mon, 02 Apr 2012 00:00:00 +0000</pubDate><author>Damian Galarza</author><guid>https://www.damiangalarza.com/posts/2012-04-02-simple-sinatra-service-proxy/</guid><content:encoded><![CDATA[<p>Recently I came across the situation where I would need to communicate with a third party API on the front
end via JavaScript and some AJAX requests. Unfortunately JavaScript does not allow ajax requests across different
domains which caused an issue for us since the service does not support a JSONP service to get around this.</p>
<p>Instead, I set out to build a back end service which would consume our third party API and we could interact
with on the front end. However, I did not want to spend a great deal of time on building this midpoint between
the services.</p>
<h3 id="ruby-and-sinatra-to-the-rescue">Ruby and Sinatra to the Rescue</h3>
<p>Armed with the task at hand I set out to build the simplest approach possible to begin consuming our third party
API as quickly as possible. I started out with Rails and a look into ActiveResource but quickly found that there was
to much overhead and complexity for what I needed. With this in mind I decided to move onto a simple Sinatra application which
would aim to mimic the third party services in API methods and forward requests for us.</p>
<p>For our test case, let&rsquo;s look at the Twitter API. Note, Twitter does in fact support a JSONP service so this isn&rsquo;t really necessary.
We are simply using it as a test case for the post.</p>
<h4 id="fetching-a-users-timeline">Fetching a user&rsquo;s timeline</h4>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#89dceb">require</span> <span style="color:#a6e3a1">&#39;sintra&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#89dceb">require</span> <span style="color:#a6e3a1">&#39;net/http&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>get <span style="color:#a6e3a1">&#34;/1/statuses/user_timeline&#34;</span> <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>    uri <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#f9e2af">URI</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">HTTP</span><span style="color:#89dceb;font-weight:bold">.</span>build(
</span></span><span style="display:flex;"><span>        <span style="color:#a6e3a1">:host</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> api<span style="color:#89dceb;font-weight:bold">.</span>twitter<span style="color:#89dceb;font-weight:bold">.</span>com,
</span></span><span style="display:flex;"><span>        <span style="color:#a6e3a1">:path</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> request<span style="color:#89dceb;font-weight:bold">.</span>path_info,
</span></span><span style="display:flex;"><span>        <span style="color:#a6e3a1">:query</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> request<span style="color:#89dceb;font-weight:bold">.</span>query_string
</span></span><span style="display:flex;"><span>    )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    content_type <span style="color:#a6e3a1">&#39;application/json&#39;</span>, <span style="color:#a6e3a1">:charset</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> <span style="color:#a6e3a1">&#39;utf-8&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f9e2af">Net</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">HTTP</span><span style="color:#89dceb;font-weight:bold">.</span>get(uri)
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span></code></pre></div><p>In order to fetch a user&rsquo;s timeline we will need to make a request to the following API path: <code>/1/statuses/user_timeline</code>. Along with this path
the API documentation by twitter specifies that we can send various parameters along in the query string. What we have done here is we created a path which matches
twitter&rsquo;s and from there we access the request information provided by Sinatra. We build a URI using the API URL, <code>request.path</code>, and <code>request.query</code>. This will allow us
to quickly forward the request to Twitter&rsquo;s API through a NET::HTTP.get request.</p>
<p>Now that we&rsquo;ve done that we can either mount our Sinatra app somewhere in the same domain or proxy requests to it on another domain.  In my case, I&rsquo;ve set up a simple
proxy through Apache at /services.</p>
<pre tabindex="0"><code>&lt;IfModule mod_proxy.c&gt;
    ProxyRequests Off
    ProxyVia On

    &lt;Proxy *&gt;
        AddDefaultCharset off
        Order deny, allow
        Allow from all
    &lt;/Proxy&gt;

    ProxyPass /services http://127.0.0.1:9393
    ProxyPassReverse /services http://127.0.0.1:9393
&lt;/IfModule&gt;
</code></pre><p>So assuming I have my Sinatra application up and running on port 9393. I now have a proxy which will forward all requests to /services in my web application
to the Sinatra application. This will then forward all requests to the Twitter API and return the results. Visit the <a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html">mod_proxy</a> documentation
for more information about HTTP proxies with Apache.</p>
<h4 id="drying-up-our-application">Drying up our application</h4>
<p>In our case right now we have a single method that we are forwarding, but what if we wanted to support more API methods provided by twitter.  Well we could go ahead and write out
each method and its block, or we could take advantage of the flexibility we have available to us.</p>
<div class="highlight"><pre tabindex="0" style="color:#cdd6f4;background-color:#1e1e2e;-moz-tab-size:2;-o-tab-size:2;tab-size:2;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#89dceb">require</span> <span style="color:#a6e3a1">&#39;sinatra&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#89dceb">require</span> <span style="color:#a6e3a1">&#39;net/http&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">def</span> <span style="color:#89b4fa">api_request</span>(path, query_string)
</span></span><span style="display:flex;"><span>    uri <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#f9e2af">URI</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">HTTP</span><span style="color:#89dceb;font-weight:bold">.</span>build(
</span></span><span style="display:flex;"><span>        <span style="color:#a6e3a1">:host</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> api<span style="color:#89dceb;font-weight:bold">.</span>twitter<span style="color:#89dceb;font-weight:bold">.</span>com,
</span></span><span style="display:flex;"><span>        <span style="color:#a6e3a1">:path</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> path,
</span></span><span style="display:flex;"><span>        <span style="color:#a6e3a1">:query</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> query_string
</span></span><span style="display:flex;"><span>    )
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f9e2af">Net</span><span style="color:#89dceb;font-weight:bold">::</span><span style="color:#f9e2af">HTTP</span><span style="color:#89dceb;font-weight:bold">.</span>get uri
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>request_handler <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#89dceb;font-weight:bold">-&gt;</span> <span style="color:#cba6f7">do</span>
</span></span><span style="display:flex;"><span>    content_type <span style="color:#89dceb;font-weight:bold">=</span> <span style="color:#a6e3a1">&#39;application/json&#39;</span>, <span style="color:#a6e3a1">:charset</span> <span style="color:#89dceb;font-weight:bold">=&gt;</span> <span style="color:#a6e3a1">&#39;utf-8&#39;</span>
</span></span><span style="display:flex;"><span>    api_request request<span style="color:#89dceb;font-weight:bold">.</span>path_info, request<span style="color:#89dceb;font-weight:bold">.</span>query_string
</span></span><span style="display:flex;"><span><span style="color:#cba6f7">end</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e3a1">%w{
</span></span></span><span style="display:flex;"><span><span style="color:#a6e3a1">    /1/statues/user_timeline
</span></span></span><span style="display:flex;"><span><span style="color:#a6e3a1">    /1/statuses/mentions
</span></span></span><span style="display:flex;"><span><span style="color:#a6e3a1">    /1/statuses/retweeted_by_me
</span></span></span><span style="display:flex;"><span><span style="color:#a6e3a1">}</span><span style="color:#89dceb;font-weight:bold">.</span>each { <span style="color:#89dceb;font-weight:bold">|</span>route<span style="color:#89dceb;font-weight:bold">|</span> get route, <span style="color:#89dceb;font-weight:bold">&amp;</span>request_handler }
</span></span></code></pre></div>]]></content:encoded></item></channel></rss>