Jekyll2021-07-06T12:01:23+05:30https://blog.harigopal.in/feed.xmlHari GopalMy thoughts on programming, and more.
A Complete Guide to Setting up a GraphQL Server on Rails2019-11-05T20:20:00+05:302019-11-05T20:20:00+05:30https://blog.harigopal.in/guides/a-complete-guide-to-setting-up-a-graphql-server-on-rails<h2 id="introduction">Introduction</h2>
<p><em>“Convention over configuration”</em> is one of the reasons Rails became as popular as it did. Conventions allow developers to be productive without <a href="https://en.wiktionary.org/wiki/bikeshedding"><em>bike-shedding</em></a>. However, introducing new concepts to Rails involves a period of experimentation during which there are no answers to troublesome questions.</p>
<p>Setting up a GraphQL server on Rails is one of those tasks.</p>
<p>This post presents a method for setting up a GraphQL server, while also tackling two issues that are generally glossed over by existing documentation surrounding the use of the <code class="language-plaintext highlighter-rouge">graphql-ruby</code> gem:</p>
<ol>
<li>How do I handle authorization?</li>
<li>How do I avoid N+1 queries?</li>
</ol>
<h2 id="start-with-graphql-ruby">Start with <em>graphql-ruby</em></h2>
<p>We’ll be using the <a href="https://graphql-ruby.org/getting_started">well-documented <code class="language-plaintext highlighter-rouge">graphql-ruby</code> gem</a> to get started with setting up a GraphQL server on Rails. If you’re someone who’s already familiar with <code class="language-plaintext highlighter-rouge">graphql-ruby</code>, feel free to <a href="#here-be-dragons">skip this section</a>.</p>
<ol>
<li>Add <code class="language-plaintext highlighter-rouge">gem 'graphql-ruby', '~> 1.9'</code> to your <code class="language-plaintext highlighter-rouge">Gemfile</code>.</li>
<li>Run <code class="language-plaintext highlighter-rouge">bundle install</code> on the command line.</li>
<li>Run the gem’s installation generator: <code class="language-plaintext highlighter-rouge">rails generate graphql:install</code>.
<ul>
<li>If Rails complains that it can’t find <code class="language-plaintext highlighter-rouge">graphql:install</code>, try again after stopping <code class="language-plaintext highlighter-rouge">spring</code>, with <code class="language-plaintext highlighter-rouge">bin/spring stop</code>.</li>
</ul>
</li>
<li>The previous step will have updated the <code class="language-plaintext highlighter-rouge">Gemfile</code>, so you’ll need run <code class="language-plaintext highlighter-rouge">bundle install</code> again.</li>
</ol>
<p>At this point, <code class="language-plaintext highlighter-rouge">graphql-ruby</code> is all set up. Let’s take a quick look at what the gem added to our Rails application, so that the following steps are easier to understand.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>app/
├─ config/routes.rb (updated to include /graphql, and /graphiql)
├─ controllers/
| └─ graphql_controller.rb (all requests are handled by the execute action)
└─ graphql/
├─ my_rails_app_schema.rb (the web of interconnected types starts here)
├─ types/
| ├─ query_type.rb (base type for all queries)
| ├─ mutation_type.rb (base type for all mutations)
| └─ base_*.rb (many other base types - object, enum, etc.)
└─ mutations/
└─ .keep (empty - we haven't made any mutations yet)
</code></pre></div></div>
<p>If we take a look inside the <code class="language-plaintext highlighter-rouge">routes.rb</code> file, we can see that a new <code class="language-plaintext highlighter-rouge">/graphql</code> path is handled by the <code class="language-plaintext highlighter-rouge">GraphqlController#execute</code> method:</p>
<script src="https://gist.github.com/harigopal/877e2d5c9f79c1c1887e8ee9538d1bdd.js"></script>
<p>Notice how the incoming query is passed onto the schema (along with <em>context</em>) for execution. The <em>schema</em> defines only two things right now:</p>
<script src="https://gist.github.com/harigopal/d6a8c4e27e1df99c7ef84db39b9b5e5e.js"></script>
<p>The schema says that mutations can be found in <code class="language-plaintext highlighter-rouge">Types::MutationType</code> and queries in <code class="language-plaintext highlighter-rouge">Types::QueryType</code>. If we take a look in either, we’ll see a dummy field that we can play around with.</p>
<p>One thing that I glossed over in <code class="language-plaintext highlighter-rouge">routes.rb</code> is that the gem also mounted the awesome <em>GraphiQL</em> app on the <code class="language-plaintext highlighter-rouge">/graphiql</code> path. Visit the <code class="language-plaintext highlighter-rouge">/graphiql</code> path in your browser, and try running the following query there:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>query {
testField
}
</code></pre></div></div>
<p>You should get this response:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"data": {
"testField": "Hello World!"
}
}
</code></pre></div></div>
<p>There you go! Now that we’re done with our whirlwind tour of the <code class="language-plaintext highlighter-rouge">graphql-ruby</code> gem, let’s start digging a bit deeper.</p>
<h2 id="here-be-dragons">Here Be Dragons</h2>
<p>While the <code class="language-plaintext highlighter-rouge">graphql-ruby</code> gem has added a <em>ton</em> of functionality to our app, it doesn’t really go into detail as to what the best practices are for actually <em>using</em> the gem. Specifically, as mentioned at the beginning of this guide, two issues that are glossed over are:</p>
<ol>
<li>How to handle authorization, and…</li>
<li>How to efficiently query data.</li>
</ol>
<p>Just like the <a href="https://graphql.org/learn/authorization/">official documentation about authorization in GraphQL</a>, the <a href="https://graphql-ruby.org/authorization/overview.html#authorization-in-your-business-logic">gem’s documentation</a> also suggests pushing the responsibility for authorization into <em>business</em> logic, specifically into model methods that accept <code class="language-plaintext highlighter-rouge">context</code> and decide what kind of relation or data is accessible for <em>that</em> user.</p>
<p>As for the potential for N+1 queries, it’s pretty much ignored altogether - I’m guessing that you’re expected to handle this on a case-by-case basis.</p>
<p>I’d like to suggest an alternative: new <em>conventions</em>.</p>
<h2 id="resolvers-authorize-and-fetch-data"><em>Resolvers</em> authorize and fetch data</h2>
<p>Let’s start by adding an <code class="language-plaintext highlighter-rouge">ApplicationQuery</code> class that’ll act as the base class for <em>resolvers</em> and <em>mutators</em>:</p>
<script src="https://gist.github.com/harigopal/2270db1662f697fbbf8fd3303aca2029.js"></script>
<p>With that in place, we can start writing <em>resolver</em> objects that will help us retrieve properly authorized data for GraphQL queries. Let’s start by creating a query that asks for a list of users:</p>
<script src="https://gist.github.com/harigopal/124000d16b0188d283c6ed92763b1f4e.js"></script>
<p>Notice how the <code class="language-plaintext highlighter-rouge">users</code> method simply hands over the responsibility for loading the data to a <code class="language-plaintext highlighter-rouge">UsersResolver</code> object:</p>
<script src="https://gist.github.com/harigopal/d498086083b1db7180e407b43dbf7193.js"></script>
<p>What you’re looking at is the essence of this approach.</p>
<ol>
<li>All requests are individually authorized.</li>
<li>There is an assumption that once a query is authorized, all data returned by the resolver (or mutator) can be accessed by the authenticated user.</li>
<li>Avoid N+1-s by making sure that the resolver method <code class="language-plaintext highlighter-rouge">includes</code> all necessary data for the response.</li>
</ol>
<p>Before we move onto mutators, let’s also look at how we deal with queries that have arguments, using a variation of what we’ve done above:</p>
<script src="https://gist.github.com/harigopal/d189b80d9d62acdde4bb6e4f8bd4d364.js"></script>
<p>Only a few things are different here:</p>
<ol>
<li><code class="language-plaintext highlighter-rouge">args</code> is passed to the resolver in addition to context.</li>
<li>There’s a <code class="language-plaintext highlighter-rouge">property :id</code> in the resolver class defining what data the query will work with.</li>
<li>Instead of a relation, the <code class="language-plaintext highlighter-rouge">user</code> method in the resolver returns a <code class="language-plaintext highlighter-rouge">User</code> object, since the <em>type</em> for the query is a single object.</li>
</ol>
<h2 id="mutators-authorize-modify-and-supply-a-response"><em>Mutators</em> authorize, modify, and supply a response</h2>
<p>GraphQL mutations aren’t really all that different from queries. Mutations are queries that are, <em>by convention</em>, allowed to modify data. And just like queries, they too can return structured data.</p>
<p>As with queries, let’s start with a simple example that shows just how similar <em>mutators</em> are to <em>resolvers</em>.</p>
<script src="https://gist.github.com/harigopal/da0fe5301af5027e84ec0f0f9a5c83dc.js"></script>
<p>Notice how there’s a call to <code class="language-plaintext highlighter-rouge">.valid?</code> before the <code class="language-plaintext highlighter-rouge">.create_comment</code> is called. This triggers validations that can be configured in the mutator class:</p>
<script src="https://gist.github.com/harigopal/d64f6273011582b657af7a8a0bc30797.js"></script>
<p>Again, there’s very little that’s new here.</p>
<ol>
<li>Because <code class="language-plaintext highlighter-rouge">ApplicationQuery</code> includes <code class="language-plaintext highlighter-rouge">ActiveModel::Model</code>, we have access to all of the validation methods that we’re familiar with.</li>
<li>The <code class="language-plaintext highlighter-rouge">property</code> helper simply combines <code class="language-plaintext highlighter-rouge">validates</code> and <code class="language-plaintext highlighter-rouge">attr_accessor</code> into a single-step, and helps avoid bugs because the former depends on the latter.</li>
<li>We can either process the request in the mutator directly in the <code class="language-plaintext highlighter-rouge">create_comment</code> method, or pass it onto a service as shown in the example.</li>
</ol>
<p>As with queries, there is an assumption that the <code class="language-plaintext highlighter-rouge">create_comment</code> method will return an object that responds to the <em>fields</em> mentioned in the mutation class. In this case, that’s <code class="language-plaintext highlighter-rouge">id</code>, and as long as the service returns a <code class="language-plaintext highlighter-rouge">Comment</code> object, everything should work as expected.</p>
<h3 id="create-types-for-complex-returns">Create types for complex returns</h3>
<p>While GraphQL unsubtly suggests the use of relations in your response types, there is no need to follow that pattern. Often, it’s much more straight-forward to create a custom type that fits exactly the data that you want to return:</p>
<script src="https://gist.github.com/harigopal/caba32c4f40f70c6ff8204def6281602.js"></script>
<p>Here, the custom <code class="language-plaintext highlighter-rouge">UpdatePostType</code> is used to compose exactly what the UI requires in this imaginary app, when a post is updated.</p>
<h2 id="what-are-the-advantages-of-this-approach">What are the advantages of this approach?</h2>
<p><strong>On the server-side:</strong></p>
<ol>
<li>You have a self-documenting API. Testing it is a breeze thanks to GraphiQL.</li>
<li>The Rails server will crash with a useful error message if your code ever disobeys the type specification.</li>
<li>Pagination of resources is simple and straight-forward, thanks to <a href="https://graphql-ruby.org/relay/connections.html">built-in, well-thought-out conventions</a> that cover a large variety of pagination-use-cases.</li>
<li>Avoids a lot of bike-shedding. <code class="language-plaintext highlighter-rouge">PUT</code> vs <code class="language-plaintext highlighter-rouge">PATCH</code>? <code class="language-plaintext highlighter-rouge">400</code> vs <code class="language-plaintext highlighter-rouge">422</code>? How to handle deprecation? These questions, and more, are no longer concerns.</li>
<li>The server’s response can be extended to include more standardized behavior.</li>
</ol>
<p><strong>On the client-side (assuming that you’re using a typed language):</strong></p>
<ol>
<li>Your API is integrated with the editor - it’ll suggest names, arguments, and return values - writing correct queries is much simpler.</li>
<li>Your compiler will prevent the application from generating code with invalid queries.</li>
</ol>
<h3 id="about-extensibility">About extensibility</h3>
<p>Your server always supplies a JSON response. This means that you can add more fields to it if you’d like.</p>
<p>In <a href="https://www.pupilfirst.com">PupilFirst</a>, we’ve expanded the response object to include a <code class="language-plaintext highlighter-rouge">notifications</code> field. If present, the response handler in the client automatically converts them into <em>flash</em> notifications that are shown to the user. This helps us preserve a <em>Rails-like</em> experience in our mutators, and keeps notifications <em>DRY</em>:</p>
<script src="https://gist.github.com/harigopal/0b208181f942adb7cc5beccbfdd5531a.js"></script>
<p>The query superclass has simple methods that inject notifications into the context…</p>
<script src="https://gist.github.com/harigopal/0b480036b4a5213077c538f49f19f87b.js"></script>
<p>…which then gets placed in the response by the GraphQL controller:</p>
<script src="https://gist.github.com/harigopal/675ef7e93ac142cef4a9d7bc1038b091.js"></script>
<h2 id="however-concerns-still-exist">However, concerns still exist</h2>
<h3 id="this-isnt-what-graphql-promised">This isn’t what GraphQL promised</h3>
<p>One of the stated advantages of GraphQL is that it solves the problem of over-fetching by allowing the client to specify exactly what data it needs, leading to the server fetching <em>only</em> the asked-for data.</p>
<p>This approach definitely <strong>ignores</strong> that goal. We’re taking this approach because of two reasons:</p>
<ol>
<li>Over-fetching is not a problem for <a href="https://www.pupilfirst.com">us</a>. It might become a problem <em>at scale</em>, but we’re not at that size yet. It’s generally better to tackle problems that exist now (ease of API usage, and avoiding clerical mistakes), instead of one that <em>might</em> happen in the future.</li>
<li>GraphQL doesn’t actually <em>do</em> anything to solve over-fetching - it just specifies how to deliver the data once you’ve retrieved it. However, retrieving data correctly is <a href="https://graphql.org/learn/thinking-in-graphs/#business-logic-layer">still up to your <em>business logic</em></a>, which is always vaguely defined in all documentation that I’ve come across.</li>
</ol>
<p>Arbitrarily loading relational data and incurring huge performance hits is one of the easiest mistakes to make with GraphQL, and it’s not a problem whose solution is clear. At this point, I think it’s appropriate to mention that Shopify has released a <a href="#"><code class="language-plaintext highlighter-rouge">graphql-batch</code> gem</a> that <em>claims</em> to tackle this issue. Unfortunately, I think it’s poorly documented, and I couldn’t really make sense of how it’s supposed to work, but it may be worth looking at if you’re already <em>at scale</em>, and dealing with issues like over-fetching.</p>
<h3 id="why-not-authorize-fields">Why not authorize fields?</h3>
<p>The simple answer is that it’s much easier to think about authorizing requests rather than fields. Requests always have a context which can be used to determine whether <em>this</em> user is allowed to access some data or make a change.</p>
<p>However, if the fields that a client can request are unbounded, i.e., the type allows the client to dig deeper into relationships and ask for <em>distant</em> data, then field-level authorization is your only option. This is why we suggest creating response types specific to queries if the requested data is complicated. Yes, this is restrictive, but requires only one authorization, and ensures that we’re limiting the response to a selection of data that we know the client is <em>definitely</em> allowed to access.</p>
<h3 id="how-is-this-any-different-from-rest">How is this any different from REST?</h3>
<p>First, I’d like to point you to the list of advantages written above.</p>
<p>You’ll notice that the process I’ve suggested is very similar to how REST works. And you know what? REST has some <em>really</em> good ideas about how to manage communication - it’s just that <em>some</em> of its requirements don’t make sense anymore when building APIs. REST has an uncomplicated approach to authorization and data-delivery that I think we should adopt even when we’re using GraphQL.</p>
<h2 id="a-real-world-example">A real-world example</h2>
<p>If you’d like to take a look at a Rails application that uses this approach, take a look at codebase for <a href="https://github.com/SVdotCO/pupilfirst">the PupilFirst LMS</a>. The patterns described here were created as <a href="https://www.sv.co">our team</a> gradually switched to using ReasonML and ReasonReact on the front-end, and adopted GraphQL in order to leverage the presence of types and a compiler.</p>IntroductionApplication State is not the answer2019-10-05T11:00:00+05:302019-10-05T11:00:00+05:30https://blog.harigopal.in/guides/application-state-is-not-the-answer<p>So… this is a total retraction of my <a href="https://blog.harigopal.in/guides/application-state-in-reasonreact">last</a> <a href="https://blog.harigopal.in/guides/revisiting-application-state-in-reason-react">two</a> posts.</p>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201910/deja-vu.png" alt="Deja vu" /></p>
<h2 id="mistakes-were-made">Mistakes were made</h2>
<p>Using application state, or global state, is <em>not</em> the right answer for developing front-end components.</p>
<p>The draw of application state is the creation of a <em>definitive</em> single-source of truth from which our entire app’s state can be determined. Then, this <em>definitive</em> state becomes the one and <em>only</em> place where you need to <em>query</em> state. And because it is ubiquitous, adding a new shared property becomes extremely simple; add it once, and it’s available everywhere.</p>
<p>This ease of modification is, unfortunately, double-edged. I’ve noticed two messy patterns arise once global state is available.</p>
<h3 id="there-is-no-local-everything-is-global">There is no <em>local</em>; everything is <em>global</em></h3>
<p>The lure of global state is such that once it is implemented, it has a tendency to <em>supplant</em> local state management. Simple UI changes that could have been implemented as local state changes creep into global state because their values <em>could</em> be used to affect other components in <em>cool</em> ways.</p>
<p>Here’s a simple example of this: On <em>Turaku</em> (my <em>late</em> pet password manager project), editing the title of any <em>entry</em> using the <em>editor</em> component changes the title of the entry in the <em>entries list</em> component immediately. This was extremely easy to implement because the two components shared the data about entries via the application state.</p>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201910/turaku-editing-entry-title.gif" alt="Editing title of an entry in Turaku" /></p>
<p>The drawback is that even though the responsibility for <em>changing</em> an entry lies logically with the editor component, something as simple as <em>saving</em> changes becomes a sticky proposition. Questions arise:</p>
<ul>
<li>What happens if the user clicks on another entry in the list when one has unsaved changes? Sure, the unsaved changes would persist - they’re in app state, but the old editor would be unmounted eventually…</li>
<li>So which part of the UI should the user interact with to initiate the save?</li>
<li>Maybe we should auto-save if the editor un-mounts as a result of user switching to another view..? But which part of the UI would show that there is a network operation on-going? What happens if the network operation fails?</li>
</ul>
<p>The last option is what I went with, and I never answered all of the questions fully. I just slapped a few chunks of code together to get everything working, and promised myself that I would get around to cleaning it up eventually.</p>
<p>This was me ignoring the <em>KISS</em> principle.</p>
<p>The <em>simple</em> solution here would have been to isolate the <em>edited</em> state of an entry to the component that <em>does</em> the editing - the editor, and communicate changes to higher-level components only once those changes were persisted. A simple UI curtain could have been employed to ensure that users couldn’t interact with unrelated parts of the UI while the edit was in progress.</p>
<p>What should have been simple - making a few edits to an entry, and then saving it ended up involving <em>many</em> different components, and is now unnecessarily complicated because I couldn’t say “No” to a few cool things.</p>
<h3 id="application-state-is-god-all-responsibilities-are-centralised">Application state is god; all responsibilities are centralised</h3>
<p>I think that <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">SRP</a> is more of a <em>guideline</em> than a <em>rule</em> when it comes to writing applications, but by its very nature, application state seems <em>require</em> that SRP be <em>broken</em>.</p>
<p>When we collect state from different parts of the application, it’s almost impossible for all of these values to be (closely) related. Usually, they’re collected over time as the application’s feature-set expands and evolves, and as such they’re going to be incorporated into a single reducer that, increasingly needs to handle values with different purposes.</p>
<p>The issue that pops up as a result is increased <em>cognitive load</em>. It’s easy to make changes when the number of things that <em>can</em> change is low. The larger the size of the state being managed by a reducer, the harder it is to simply fit all of its variables into <em>our</em> working memory.</p>
<p>When asked for his opinion, here’s what <a href="http://www.jasimabasheer.com/">Jasim</a> had to say about this topic:</p>
<blockquote>
<p>One solution to large reducers that we’ve been using more and more is to lean on domain-specific modules, and use the reducer just as a very high-level dispatcher.</p>
<p>UI handler functions in lower-level components can run their own computation and then pass final results back to a reducer. This keeps the responsibility of each domain closer to the component that handles it, and the implementations are all co-located neatly in their own modules.</p>
</blockquote>
<h2 id="back-to-basics">Back to Basics</h2>
<p>When reaching for global / application state as a solution from our toolbox, its critical to examine whether it’s worth the costs involved, and whether we’re being careful to avoid the pitfalls that it exposes.</p>
<p>State-management based on localized state with plentiful prop drilling might not be <em>stylish</em>, but it’s based on sound development practises, works <em>really</em> well in most situations, and should be the default choice for React and ReasonReact applications of any level of complexity.</p>
<p>As for my pet project, it’s future is uncertain. I started working on it when I was still a beginner with ReasonML, and the mistakes I made while learning have piled up. Its state management is, quite frankly, a mess. However, thanks to those mistakes, by the time I introduced ReasonML & ReasonReact to my full-time work, I knew enough to be conservative.</p>
<p>Right now, I’m focusing on building <a href="https://www.pupilfirst.com">PupilFirst</a> - an LMS that my company open-sourced recently, and which we’ve been working on since 2013. It mixes Ruby, ReasonML & GraphQL, and is probably one of the largest open-source ReasonReact webapps out there.</p>So… this is a total retraction of my last two posts.Revisiting Application State in ReasonReact2018-09-08T15:30:00+05:302018-09-08T15:30:00+05:30https://blog.harigopal.in/guides/revisiting-application-state-in-reason-react<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201809/frame_1_oops.png" alt="Oops" /></p>
<h2 id="tldr-aka-just-tell-me-what-you-were-wrong-about">TL;DR (aka, just tell me what you were wrong about)</h2>
<ol>
<li>Passing <code class="language-plaintext highlighter-rouge">appState</code> to all components is not a good idea. <code class="language-plaintext highlighter-rouge">appState</code> contains <em>unresolved possible states</em> that individual components usually don’t care about, but, which you’ll still be forced to handle since ReasonML is a strongly typed language.</li>
<li>Instead of passing state, pass <code class="language-plaintext highlighter-rouge">ctx</code> (context). My current approach is to pass a <code class="language-plaintext highlighter-rouge">ctx</code> record to each component that contains the <em>resolved</em> information <em>derived</em> from state, that the particular component <em>needs</em>. This allows the component to function with <em>certain knowledge</em> about the context in which it will render.</li>
<li>Passing <code class="language-plaintext highlighter-rouge">appSend</code> to all components (like before) is fine — it’s just a function with which we <em>affect</em> application state.</li>
</ol>
<h2 id="and-in-much-more-detail">And in much more detail…</h2>
<p>I’d written about a method to maintain <a href="https://medium.com/@elvesbane/application-state-in-reasonreact-1626859366a8">Application State in ReasonReact</a> back in April, and I’ve worked with ReasonML a lot more since then, completing the conversion of <a href="https://github.com/turakuapp/turaku-client/">Turaku’s codebase</a> from ES6 to Reason, and it turns out that my approach in the previous article didn’t <em>work</em> as well as I expected it to.</p>
<p>Passing around application state as <code class="language-plaintext highlighter-rouge">appState</code> is a bad idea with ReasonML. Passing around <code class="language-plaintext highlighter-rouge">appSend</code> appears to be fine.</p>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201809/frame_2_return.png" alt="Do not pass appState" /></p>
<p>Why? Well, one of the basic tenants of functional programming is to <em>make illegal states unrepresentable</em>. Put simply, it means that the structures that define and hold our data should not allow the possibility of incorrect state. This is nearly impossible to achieve with dynamically typed languages, and unless this is a principle you’ve already grokked, do yourself a favour and watch Richard Feldman’s awesome talk titled “<a href="https://www.youtube.com/watch?v=IcgmSRJHu_8">Making Impossible States Impossible</a>”.</p>
<p>I’m gonna continue assuming that you’ve watched the video.</p>
<p>One of the tools that ReasonML gives us to describe a <em>thing</em> that could be <em>one of a set of things</em> is something called <em>Variant</em> (union type). In Turaku’s application state definition, there are types that looks a bit like this (simplified):</p>
<script src="https://gist.github.com/harigopal/15dc0ae18cbfe96852755a9c3b505a59.js"></script>
<p>Looking at the basic type <code class="language-plaintext highlighter-rouge">state</code>, it’s pretty easy to tell that we’ve described our user’s state in the application as <em>always</em> being one of two — either the user is signed out (and on a public page), or the user is signed in (and has some corresponding user data).</p>
<p><em>Variants</em> allow ReasonML’s compiler to ensure that whenever we handle a value of a <em>variant</em> type, all of its possibilities are considered. For example, in the root component, when trying to determine which view to render, we could use <code class="language-plaintext highlighter-rouge">switch</code>, like so:</p>
<script src="https://gist.github.com/harigopal/d902f64731da6718127a022dced3a0c1.js"></script>
<p>The compiler can be configured to either issue warnings or raise errors if we’ve forgotten to deal with all the defined <em>variants</em> that a type can <em>be</em>. You’ll notice that I’m not passing <code class="language-plaintext highlighter-rouge">appState</code> to any of these components, yet. So let’s try that with the <code class="language-plaintext highlighter-rouge">Dashboard</code> component.</p>
<p>The <code class="language-plaintext highlighter-rouge">Dashboard</code> contains the main user interface that a signed in user is expected to interact with. Let’s send it <code class="language-plaintext highlighter-rouge">appState</code> and <code class="language-plaintext highlighter-rouge">appSend</code> …</p>
<script src="https://gist.github.com/harigopal/e1b76503351eb7510389ac5c7dd56c66.js"></script>
<p>… and then take a peek inside <code class="language-plaintext highlighter-rouge">Dashboard</code> to see how we could render a list of available teams:</p>
<script src="https://gist.github.com/harigopal/9c687bd91dce3b2b6ebed0447a3f946d.js"></script>
<p>The problem should be obvious now. <code class="language-plaintext highlighter-rouge">appState</code> is a <em>variant</em> (or can contain nested variants), and its contents can only be accessed through pattern-matching. Because of this, the component is being forced to handle all possible cases even though we know that the dashboard will never be rendered without a user being signed in.</p>
<p>Thankfully, the fix is simple. It is to <strong>not</strong> pass application state around.</p>
<p>Application state is a structure that represents all possible states that the application could be in. However, the process of rendering an <em>inner</em> component involves the <em>condensing</em> of those possibilities. What we <em>should</em> do, is to define the <em>context</em> in which the component is expected to render.</p>
<p>In the above example, it is meaningless for the <code class="language-plaintext highlighter-rouge">Dashboard</code> component to render for a signed out user, so the fix is to ensure that the component’s expected context includes the information that is available with a signed in user…</p>
<script src="https://gist.github.com/harigopal/73081eca3487b7a8a4c4055c3e1f27ea.js"></script>
<p>Now, the compiler will make sure that the component is invoked with a valid context.</p>
<script src="https://gist.github.com/harigopal/b539377f36f449a237e954116a85b1dd.js"></script>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201809/frame_3_ctx.png" alt="A bag called context" /></p>
<p>That’s it… except… it looks like we’re back to the days of <em>prop drilling</em> - which I’d advocated against in my last article.</p>
<p>We are, but only partially. Note that we’re still passing <code class="language-plaintext highlighter-rouge">appSend</code> around, allowing us to eliminate callback functions. <code class="language-plaintext highlighter-rouge">appSend</code> gives components access to <em>all</em> of the application state reducer’s <em>actions</em>.</p>
<p>This is also where the <code class="language-plaintext highlighter-rouge">ctx</code> record comes in. I’ve found it really convenient to wrap everything in a single record so that I can pass it around functions - this also helps avoid the worst effects of prop drilling - where you’d have to thread new props around functions within components to get them where they need to be. By wrapping the props into <code class="language-plaintext highlighter-rouge">ctx</code>, and treating it as a bag of values to be accessed wherever needed, we’re restricting the <em>threading / drilling</em> to the entry and exit points of components.</p>
<p>It also makes sense for the <code class="language-plaintext highlighter-rouge">ctx</code> record to grow, as it’s passed into deeper components, with parent components <em>resolving</em> more of the possibilities of application state, and passing a more <em>definite</em> context to their children.</p>
<p>Obviously, using <code class="language-plaintext highlighter-rouge">ctx</code> record is optional. Passing individual props also works, and deciding between wrapping props or leaving them unwrapped seems to be a decision between reducing the overhead of prop-drilling, or improving the cleanliness of the component call-site.</p>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201809/frame_4_jetpack.png" alt="A jetpack, not a backpack" /></p>
<h2 id="so-whats-the-takeaway">So what’s the takeaway?</h2>
<p>Passing <code class="language-plaintext highlighter-rouge">appState</code> was a <em>pattern</em> that worked well with dynamic languages. In fact, if we structure the state similar to how we’d write it in a dynamic language - without using the features that strong typing gives us (such as variants), then it’s possible to continue to use <code class="language-plaintext highlighter-rouge">appState</code>.</p>
<p><em>But</em>, if we use ReasonML <em>correctly</em>, with the intention of <em>making illegal states unrepresentable</em>, then old patterns prove insufficient. This partial retraction of mine grew out of a better understanding of how to write to functional code.</p>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201809/frame_5_fly.png" alt="Bye bye" /></p>Application State in ReasonReact2018-02-17T02:45:00+05:302018-02-17T02:45:00+05:30https://blog.harigopal.in/guides/application-state-in-reasonreact<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201802/callback_1.png" alt="The Callback Relay Race - Page 1" /></p>
<h2 id="tldr">TL;DR?</h2>
<p>I’ve modified Jared Forsyth’s tutorial on ReasonReact, improving application state management. By sending two props, <code class="language-plaintext highlighter-rouge">appState</code> and <code class="language-plaintext highlighter-rouge">appSend</code> to all child components, we allow them influence shared state directly, instead of relying on a complex web of callbacks. Sound interesting?</p>
<h2 id="go-on">Go on…</h2>
<p>Want to implement shared state in <em>ReasonReact</em> applications..?</p>
<p>Probably not, if I’m being practical. The likelyhood of you, the reader, having even heard about <em>ReasonML</em>, let alone <em>ReasonReact</em>, is small. While <em>Reason</em> was featured in <a href="https://stateofjs.com/2017/flavors/results/"><em>theStateOfJs 2017</em></a>, ~80% of survey respondents said that they’d never heard of it. So if you haven’t, that’s totally OK. Head over to <a href="https://reasonml.github.io/">ReasonML’s homepage</a> right now, and give this new (sort of?) language a spin. It’s <strong>cool</strong>, it’s built by the folks behind React, and is backed by the might of OCaml.</p>
<p>However, if you’re among the ~19.2% who’ve heard about <a href="https://reasonml.github.io/reason-react">ReasonML</a>, or the ~0.8% who’ve actually tried it <strong>and</strong> wondered about how shared / global state can work, this tutorial is for <strong>you</strong>! All of the code I’ll refer to in this article is available <a href="http://github.com/harigopal/react-re-exp">on this repo</a>.</p>
<h2 id="but-first-some-background">But first, some background</h2>
<p>Last year, <a href="https://jaredforsyth.com">Jared Forsyth</a> published <a href="https://jaredforsyth.com/2017/07/05/a-reason-react-tutorial/"><em>A ReasonReact Tutorial</em></a>, an excellent starting point for folks interested in building React applications with ReasonML. The tutorial involves building a simple Todo list app, using reducers to manage application state — a feature provided out-of-the-box by ReasonReact. The application structure looks <em>something</em> like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>App implements reducer(action)
-> TodoItem onToggle=send(Toggle)
-> TodoInput onSubmit=send(AddItem(text))
</code></pre></div></div>
<p>Here the application state is managed in the root component through a reducer, but child components can update application state only through callbacks that are passed down as props from <em>root</em>.</p>
<p>This process of passing callbacks to child components is clunky. In larger applications, where a child component can be distant from root, adding new callbacks can deteriorate into something that looks like a relay race. Here’s an example:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>App implementes editCallback(), deleteCallback(), ...
-> TodoItem editCallback=editCallback deleteCallback=deleteCallback...
-> TodoInlineEditor editCallback=editCallback deleteCallback=deleteCallback...
=> Use editCallback()
-> TodoDeleteButton deleteCallback=deleteCallback
=> Use deleteCallback()
</code></pre></div></div>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201802/callback_2.png" alt="The Callback Relay Race - Page 2" /></p>
<p><a href="#">Blair Anderson</a> wrote an excellent article titled <a href="https://medium.com/@blairanderson/you-probably-dont-need-redux-1b404204a07f">“You Probably Don’t Need Redux”</a> which explains how, in small-to-medium sized React applications, it’s often enough to pass two props — <code class="language-plaintext highlighter-rouge">appState</code> and <code class="language-plaintext highlighter-rouge">setAppState</code> to all components, allowing nested components direct access to the shared state, bypassing the need to add and <em>relay</em> individual callbacks.</p>
<p>My implementation of Jared’s tutorial mixes this idea in, and sends two props, <code class="language-plaintext highlighter-rouge">appState</code> and <code class="language-plaintext highlighter-rouge">appSend</code>, to all components that could influence shared state. For the sake of clarity, I’m only going to point out parts of the code that diverge from Jared’s tutorial.</p>
<h2 id="a-reasonable-alternative">A reasonable alternative</h2>
<script src="https://gist.github.com/harigopal/974109e09597ac17ca71d09eb4000770.js"></script>
<p><code class="language-plaintext highlighter-rouge">appState</code> as the name indicates, is the shared state, stored by the root component. <code class="language-plaintext highlighter-rouge">appSend</code> is the <code class="language-plaintext highlighter-rouge">send</code> method made available to the <code class="language-plaintext highlighter-rouge">render</code> method of the root component. We’re passing that alongside <code class="language-plaintext highlighter-rouge">appState</code>, to allow child components to trigger the root component’s reducer. The <code class="language-plaintext highlighter-rouge">TodoForm</code> component doesn’t need the <code class="language-plaintext highlighter-rouge">appState</code> prop because it never reads shared state.</p>
<script src="https://gist.github.com/harigopal/978e4e5b08431bb420fdb7a9896ada12.js"></script>
<p>When the <code class="language-plaintext highlighter-rouge">TodoItem</code> component uses the prop <code class="language-plaintext highlighter-rouge">appSend</code>, it passes an action <code class="language-plaintext highlighter-rouge">TodoApp.ToggleItem</code>. To correctly resolve the it as <code class="language-plaintext highlighter-rouge">type action</code>, we need to explicity mention the namespace — the shared module <code class="language-plaintext highlighter-rouge">TodoApp</code>. Since all components need access to the type definition of <em>state</em> and all possible <em>actions</em>, they <a href="https://github.com/harigopal/react-re-exp/blob/master/src/TodoApp.re">must be placed in this separate shared module</a>.</p>
<p>My first attempt at implementing this pattern kept the types <em>state</em> and <em>action</em> in the root component module. However, that just led to a circular dependency issue: <code class="language-plaintext highlighter-rouge">App -> child -> App</code>, blocking compilation. Extracting shared code to a different module fixed this.</p>
<p>That’s pretty much it. Notice how there are no callback functions anywhere?</p>
<p><img src="https://res.cloudinary.com/harigopal/image/upload/v1541686088/blog/201802/callback_3.png" alt="The Callback Relay Race - Page 3" /></p>
<h2 id="advantages-and-a-few-caveats">Advantages, and a few caveats</h2>
<p>With ReasonReact, we’re using reducers by default, so code that updates shared state is brought into the same module. Child components can now only <em>trigger</em> changes to shared state while the nature of the state change is strictly controlled by the reducer (which should be a pure function). This makes it much easier to control and ensure correctness of shared state.</p>
<p>And given that we’re using a language with a strong, inferred, and most importantly, <em>sound</em> type system, we get all of its benefits as well.</p>
<p>One thing that I’m not <em>totally</em> happy with is that I was forced to <code class="language-plaintext highlighter-rouge">open TodoApp</code> (first line in <code class="language-plaintext highlighter-rouge">App.re</code> gist above) within the <code class="language-plaintext highlighter-rouge">App</code> module. TodoApp defines the <code class="language-plaintext highlighter-rouge">state</code> and <code class="language-plaintext highlighter-rouge">action</code> types that the <code class="language-plaintext highlighter-rouge">App</code> component relies on, and I kept running into syntax errors when I tried to annotate types. All the other modules have manual type annotation when they first refer to either the shared <code class="language-plaintext highlighter-rouge">state</code> or an <code class="language-plaintext highlighter-rouge">action</code>. <em>Opening</em> TodoApp in the <code class="language-plaintext highlighter-rouge">App</code> module isn’t a big issue though, since it’s the root component.</p>
<p>Re-visiting the earlier contrived example with our new pattern, we end up with:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>TodoApp implements state and action types, and the reducer.
App uses TodoApp.state, TodoApp.action and TodoApp.reducer
-> TodoItem appState=App.state appSend=App.send
-> TodoInlineEditor appState=App.state appSend=App.send
=> props.appSend(TodoApp.Edit(todoId, text))
-> TodoDeleteButton appSend=App.send
=> props.appSend(TodoApp.Delete(todoId))
</code></pre></div></div>
<p>I think this is a clearer, and more consise approach than callback-passing. There’s no need to add more <em>batons</em> to the relay race either, when new actions need to be handled.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I’ve been working on a personal project, <a href="https://www.turaku.com">Turaku</a> - a password manager for teams, with ES6 + React, for the past couple of months, and its increasing complexity meant that the pain of refactoring and adding new features was slowly increasing from <em>mere annoyance</em> to <em>stinging</em>. In my search for a more <em>robust</em> environment, I was drifting towards Typescript when <a href="#">Jasim</a> and <a href="#">Sherin</a> of <a href="#">Protoship.io</a> suggested ReasonML as a (better) alternative.</p>
<p>While I’m still getting used to ReasonML and ReasonReact, my initial impressions have been generally positive. Both the language and the library are evolving rapidly at the moment. For example, while I was working through Jared’s tutorial and trying to adapt it to my preferences, ReasonReact updated and replaced the <code class="language-plaintext highlighter-rouge">self.reduce</code> method with the <code class="language-plaintext highlighter-rouge">self.send</code> method which is much easier to comprehend and use.</p>
<script src="https://gist.github.com/harigopal/89cddfb3ce8f0b74cfc484e2529070c0.js"></script>
<p>The ReasonML compiler error messages can be pretty confusing at times though. And all too often, it just barks that there’s <em>something</em> wrong with my syntax on a line, informs me that it crashed because of this, and asks me to file a bug on Reason’s repository. <code class="language-plaintext highlighter-rouge">¯\_(ツ)_/¯</code> Growing pains, I guess.</p>
<p>Over the next couple of months, I’ll attempt a complete re-write of Turaku’s code into ReasonML. I’d been using <code class="language-plaintext highlighter-rouge">create-react-app</code>, so the presence of <a href="https://github.com/reasonml-community/reason-scripts">reason-scripts</a> makes it simple to get started. I’m sure I’ll be writing more related to this on a later date. :-)</p>
<h3 id="credits">Credits</h3>
<p>Art by Rekha Soman: <a href="http://www.rekhasoman.com" target="_blank">www.rekhasoman.com</a></p>Validating Rails API requests with Reform2017-09-13T00:00:00+05:302017-09-13T00:00:00+05:30https://blog.harigopal.in/guides/validating-rails-api-requests-with-reform<p>I’ve written about the creation of custom exception classes to organize code in Rails web applications and APIs. However, while going through my previous article, I realized that my final example glossed over how request parameter validation failures would be detected by the API in the first place.</p>
<p>Today I want to discuss a pattern that I haven’t seen in the wild - one which uses <em>Reform</em> - form objects, decoupled from models (their description) - and exception classes to <em>beautifully</em> manage API parameter validation.</p>
<h2 id="an-intro-to-form-objects-for-those-unfamiliar-with-it">An intro to form objects, for those unfamiliar with it.</h2>
<p>If you haven’t used form objects before, know that they allow you to decouple validation of input from the user (via forms), and the validation of data managed by a <code class="language-plaintext highlighter-rouge">Model</code>. My primary reason for favoring this separation is that it allows the model validations to be less constrained than form validation.</p>
<p>Validations failures from a model should be <strong>unexpected</strong>, whereas form validations are always <strong>expected</strong> (users make mistakes) and thus should be handled as a natural part of your application. Decoupling in this manner also makes it easy to manage multiple forms that interact with one or more models, with different validation requirements. Google <code class="language-plaintext highlighter-rouge">form validation vs model validation</code> to learn more.</p>
<h2 id="but-api-s-dont-have-forms-right">But API-s don’t <em>have</em> forms. Right?</h2>
<p>No, they don’t. What they do have are end-points where you <em>POST</em> data, and expect something about your application’s database to change. Such data needs to be validated. This article is going to focus on how to use <em>Reform</em> - a library meant for validating data submitted by <em>users</em> into <em>forms</em>, to validate data submitted by <em>clients</em> to <em>API endpoints</em>. <em>Clients</em> instead of <em>users</em>, and <em>API endpoints</em> instead of <em>forms</em>. Let’s begin.</p>
<h2 id="post-apiusersinvite">POST /api/users/invite</h2>
<p>Let’s assume that we need to implement a simple <em>invite</em> route for our API - to invite other users to join our platform. It accepts just two parameters:</p>
<ol>
<li><code class="language-plaintext highlighter-rouge">name</code></li>
<li><code class="language-plaintext highlighter-rouge">email</code></li>
</ol>
<p>…and responds with a <code class="language-plaintext highlighter-rouge">200 OK</code> if the invitation can be processed.</p>
<p>However, as with all such requests, there are conditions which must be fulfilled before the request can be executed. Let’s list down three simple requirements:</p>
<ol>
<li><code class="language-plaintext highlighter-rouge">email</code> is required.</li>
<li><code class="language-plaintext highlighter-rouge">email</code> must look like an email address.</li>
<li><code class="language-plaintext highlighter-rouge">name</code> is optional, but if present, it must be longer than 3 characters.</li>
</ol>
<p>The last one is a bit contrived, but this is just a demonstration. ¯_(ツ)_/¯</p>
<h2 id="create-a-reform-form">Create a Reform Form.</h2>
<p>Let’s get the basics out of the way. Setting up <em>Reform</em> should be pretty simple. Add <code class="language-plaintext highlighter-rouge">gem 'reform-rails', '~> 0.1.7'</code> to your <code class="language-plaintext highlighter-rouge">Gemfile</code>, and run <code class="language-plaintext highlighter-rouge">bundle install</code>. That should be it. Now, let’s build our form object.</p>
<script src="https://gist.github.com/harigopal/1de28e963edeed26e9580fb00749e2a3.js"></script>
<p><code class="language-plaintext highlighter-rouge">reform-rails</code> allows you to write validations in much the same way that you’d write validations for regular Rails models. Granted that this is a very simple form, but even complex Reform forms are readable, and its API is rich and flexible.</p>
<p>If you’re confused by <code class="language-plaintext highlighter-rouge">email: true</code>, I’m assuming the presence of a custom Rails validator. For an example, check out <a href="http://guides.rubyonrails.org/active_record_validations.html#custom-validators">Rails’ documentation on adding custom validators</a>.</p>
<p>Note that I’m overriding the default <code class="language-plaintext highlighter-rouge">save</code> method, since I don’t want Reform touching the model. I advise keeping code handling the <em>actual</em> invitation out of the form. Our form is responsible for data validation, not operations. <a href="/guides/extending-ruby-on-rails-with-service-objects">Leave business logic to services.</a></p>
<h2 id="set-up-the-endpoint">Set up the endpoint.</h2>
<script src="https://gist.github.com/harigopal/ec811f2bc3cf7e9f18006a3a3349c4dd.js"></script>
<p><em>Reform</em> requires explicit validation which, I think, reads better than the <em>Rails way</em>. Unlike Rails’ <code class="language-plaintext highlighter-rouge">if @user.save</code>, <em>Reform</em> asks the form object to validate the form with the supplied params, <em>and then</em> do something if the validation passes (or something else when it fails).</p>
<p>In this case, a failure to validate lets us raise <code class="language-plaintext highlighter-rouge">ValidationException</code>, passing it the form object. This is a custom exception which <a href="/guides/exceptions-as-first-class-citizens-on-rails">I’d elaborated on in a previous article</a>. Let’s take another look.</p>
<h2 id="validationfailureexception">ValidationFailureException</h2>
<p>I’m going to extend an <code class="language-plaintext highlighter-rouge">ApplicationException</code> class that I went into detail in my article on exception classes:</p>
<script src="https://gist.github.com/harigopal/ab851d1f2a0a8bb8a4a70409ad03c2b2.js"></script>
<p>Coupled with application level exception handling, as described in my previous post, if you <em>POST</em> to the API with invalid data, it responds with a lot of detail.</p>
<script src="https://gist.github.com/harigopal/1152bb382b07e8087ffea534e602f8e8.js"></script>
<p>Isn’t that beautiful?</p>
<p>Those validation errors can now be used by the client to display the failure to the user. Obviously, this needs to be set up only once. As long as you validate params with Reform, and pass the form with the errors to <code class="language-plaintext highlighter-rouge">ValidationFailureException</code> when raising it, responses in a standard format are taken care of.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Form objects are a great abstraction that allow us to deal with of the process of validating user input in one place. If you’re building an API for other developers or the public, good documentation is an absolute necessity. And while invalid form submissions showing users what’s wrong is commonplace, APIs doing something similar for their clients is <em>rare</em>.</p>
<p>Using Reform, it’s possible to give consumers of your API insights into what went wrong the same way a user entering incorrect information into a form is treated. Sure, once set up, an API client won’t make (the same) mistake again. But when integrating with a new API, a little help can go a long way.</p>I’ve written about the creation of custom exception classes to organize code in Rails web applications and APIs. However, while going through my previous article, I realized that my final example glossed over how request parameter validation failures would be detected by the API in the first place.Extending Ruby on Rails with Service Objects2017-04-15T00:00:00+05:302017-04-15T00:00:00+05:30https://blog.harigopal.in/guides/extending-ruby-on-rails-with-service-objects<p>Service objects are a pattern that I believe should be part of Rails’ default. This extends the basic MVC model by introducing services to implement business logic (instead of stuffing it into a model). While Rails’ default assumption that each model would hold its own business logic is <em>sound</em>, it doesn’t scale well when the application’s size increases.</p>
<p>There are a lot of articles suggesting patterns on where and how to store services. My approach is mostly the same, but with a few <em>upgrades</em>. This is what an example <code class="language-plaintext highlighter-rouge">app/services</code> folder might look like:</p>
<script src="https://gist.github.com/harigopal/c0b2ddb53f3b8e0d5875c00f33beda51.js"></script>
<p>The main thing to note here is that there are a few <em>conventions</em>, but no strict <em>rules</em>.</p>
<h2 id="one-or-few-responsibilities">One, or few responsibilities</h2>
<p>Naming plays a big role here - try to keep the name as specific as possible to avoid the temptation to <em>extend</em> the responsibility of a service object. So, instead of <code class="language-plaintext highlighter-rouge">Users::SlackService</code>, it might be a better idea to call it <code class="language-plaintext highlighter-rouge">Users::SendSlackMessageService</code>.</p>
<p>Unlike models, with their attached database tables, it’s cheap (zero cost, really) to create new services - spin new ones up whenever you encounter business logic that needs to be implemented.</p>
<h2 id="service-related-to-a-model">Service related to a model</h2>
<script src="https://gist.github.com/harigopal/7ebffe156a8239ccac5d7d256adefb2c.js"></script>
<p>Services are grouped into a <em>pluralized-model-name</em> module when the action they perform is closely related to a model. This group is for the sake of organization - nothing more, so if a service does something that’s related to two models, you’ll have to make a call on which module it best fits into.</p>
<h2 id="-and-when-its-not-related-to-a-model">… and when it’s <em>not</em> related to a model</h2>
<script src="https://gist.github.com/harigopal/5789ff9820bb7d86bd815654cd16c8b7.js"></script>
<p>Frequently, business logic may not tie in directly to <em>any</em> model. In this example, there’s a third-party service that the application needs to interact with, so the module its grouped under is simply the name of the service. The <code class="language-plaintext highlighter-rouge">execute</code> method is also replaced with a <code class="language-plaintext highlighter-rouge">posts</code> method to indicate that the service returns something, instead of simply performing an action.</p>
<h2 id="concerns-to-share-abilities">Concerns to share abilities</h2>
<p>Embrace Rails concerns when you encounter pieces of functionality that is useful in a number of situations - a common one is the ability to write to the log.</p>
<script src="https://gist.github.com/harigopal/2d9d7ffeedbb360f70381559dbcb7766.js"></script>
<p>Including this module into a service will allow it to easily write to the Rails log with additional information regarding the source of the message and a timestamp.</p>
<h2 id="theyre-easy-to-test">They’re easy to test</h2>
<p>Because these are plain Ruby classes, they’re generally easy to test. If you’ve stuck to the <em>Single-resposibility Principle</em>, the test cases should be pretty simple as well - writing a lot of small services pays off here.</p>
<h2 id="conclusion">Conclusion</h2>
<p>If you’re working on a non-trivial project, services can be a massive boon. There’s definitely a <em>back-to-the-roots</em> feel to it, and that’s deliberate - Ruby is an expressive, easy-to-read language, and service objects are plain Ruby classes that describe all the little pieces that form the building blocks of your application.</p>
<p>I’ve heard it said that a someone looking through your <code class="language-plaintext highlighter-rouge">services</code> folder should get a fair idea of what your application <em>does</em>, and I think that’s an inevitable end-result if you write service objects properly.</p>Service objects are a pattern that I believe should be part of Rails’ default. This extends the basic MVC model by introducing services to implement business logic (instead of stuffing it into a model). While Rails’ default assumption that each model would hold its own business logic is sound, it doesn’t scale well when the application’s size increases.Exceptions as first-class citizens on Rails2017-02-03T00:00:00+05:302017-02-03T00:00:00+05:30https://blog.harigopal.in/guides/exceptions-as-first-class-citizens-on-rails<p>I want to share a pattern that I’ve repeated multiple times in the past when developing API-s with Rails, which grants the ability to respond to invalid requests with a standardized message format by raising an exception.</p>
<p>To be clear, I’m talking about <em>exceptions</em>, and not <em>errors</em>. To quote a <a href="https://wiki.haskell.org/Error_vs._Exception">Haskell wiki page on the topic</a>:</p>
<blockquote>
<p>…we use the term exception for <strong>expected but irregular situations</strong> at runtime and the term error for <strong>mistakes in the running program</strong> that can be resolved only by fixing the program.</p>
</blockquote>
<p>A few examples of exceptions would be a client which supplies invalid authentication credentials, or one supplying insufficient data for an operation, etc.</p>
<h2 id="preview-of-the-end-result">Preview of the end result</h2>
<p>To decide whether this interests you, have a look at the end result - a few exception responses:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">raise</span> <span class="no">Users</span><span class="o">::</span><span class="no">AuthenticationFailure</span> <span class="c1"># => HTTP 401</span>
</code></pre></div></div>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"code"</span><span class="p">:</span><span class="w"> </span><span class="s2">"authentication_failure"</span><span class="p">,</span><span class="w">
</span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Could not validate authorization"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Please authenticate and acquire JWT before attempting to access restricted routes. JWT should be passed in the Authorization header."</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">raise</span> <span class="no">Users</span><span class="o">::</span><span class="no">ValidationFailure</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">user</span><span class="p">)</span> <span class="c1"># => HTTP 422</span>
</code></pre></div></div>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"code"</span><span class="p">:</span><span class="w"> </span><span class="s2">"validation_failure"</span><span class="p">,</span><span class="w">
</span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Validation of params failed"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"The server could not validate the parameters present with the request. Please check the validation_errors key (hash) for more details."</span><span class="p">,</span><span class="w">
</span><span class="nl">"validation_errors"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">"cannot be blank"</span><span class="w"> </span><span class="p">],</span><span class="w">
</span><span class="nl">"email"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"does not look like an email address"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Let’s dig in!</p>
<h2 id="first-class">First-class</h2>
<p>I organize my exceptions inside the <code class="language-plaintext highlighter-rouge">app</code> folder, treating it as equal to any of the other piece of the Rails application:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Rails.root
├── app
... ├── channels
├── controllers
├── exceptions
│ ├── users
│ │ ├── authentication_failed_exception.rb
│ │ └── validation_failure_exception.rb
│ └── application_exception.rb
├── jobs
...
</code></pre></div></div>
<h2 id="exception-classes">Exception classes</h2>
<p>Each exception class sets four instance variables that describe the exception.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span> <span class="nn">Users</span>
<span class="k">class</span> <span class="nc">AuthenticationFailureException</span> <span class="o"><</span> <span class="no">ApplicationException</span>
<span class="k">def</span> <span class="nf">initialize</span>
<span class="vi">@code</span> <span class="o">=</span> <span class="ss">:authentication_failure</span>
<span class="vi">@message</span> <span class="o">=</span> <span class="s1">'Could not validate authorization'</span>
<span class="vi">@description</span> <span class="o">=</span> <span class="s1">'Please authenticate and acquire JWT before attempting to access restricted routes. JWT should be passed in the Authorization header.'</span>
<span class="vi">@status</span> <span class="o">=</span> <span class="mi">401</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<ul>
<li><code class="language-plaintext highlighter-rouge">code</code> is useful for clients to programmatically handle these responses.</li>
<li><code class="language-plaintext highlighter-rouge">message</code> is a short error message.</li>
<li><code class="language-plaintext highlighter-rouge">description</code> is a longer message that can help developers understand the reason for the exception, and fix or incorporate it into the design of the client.</li>
<li><code class="language-plaintext highlighter-rouge">status</code> is an over-ride status code for the HTTP response.</li>
</ul>
<h2 id="applicationexception">ApplicationException</h2>
<p>The <code class="language-plaintext highlighter-rouge">ApplicationException</code> class defines the response object and a default HTTP status code.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">ApplicationException</span> <span class="o"><</span> <span class="no">StandardError</span>
<span class="k">def</span> <span class="nf">response</span>
<span class="p">{</span> <span class="ss">code: </span><span class="vi">@code</span><span class="p">,</span> <span class="ss">message: </span><span class="vi">@message</span><span class="p">,</span> <span class="ss">description: </span><span class="vi">@description</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">status</span>
<span class="vi">@status</span> <span class="o">||</span> <span class="mi">422</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<h2 id="bringing-it-to-life-with-rescue_from">Bringing it to life with rescue_from</h2>
<p>On the <code class="language-plaintext highlighter-rouge">ApplicationController</code>, we handle raised <code class="language-plaintext highlighter-rouge">ApplicationException</code>-s as follows:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">ApplicationController</span> <span class="o"><</span> <span class="no">ActionController</span><span class="o">::</span><span class="no">API</span>
<span class="c1"># ...</span>
<span class="n">rescue_from</span> <span class="no">ApplicationException</span><span class="p">,</span> <span class="ss">with: :show_exception</span>
<span class="c1"># ...</span>
<span class="kp">protected</span>
<span class="k">def</span> <span class="nf">show_exception</span><span class="p">(</span><span class="n">exception</span><span class="p">)</span>
<span class="n">render</span> <span class="ss">json: </span><span class="n">exception</span><span class="p">.</span><span class="nf">response</span><span class="p">,</span> <span class="ss">status: </span><span class="n">exception</span><span class="p">.</span><span class="nf">status</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>This allows us to raise custom exceptions from any location while handling a request.</p>
<h2 id="adding-more-detail-to-exceptions">Adding more detail to exceptions</h2>
<p>Note that the second preview example included a <code class="language-plaintext highlighter-rouge">validation_errors</code> key with extra information about the event. Using plain objects allows us to add or modify the response as per our requirements.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span> <span class="nn">Users</span>
<span class="k">class</span> <span class="nc">ValidationFailureException</span> <span class="o"><</span> <span class="no">ApplicationException</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="vi">@code</span> <span class="o">=</span> <span class="ss">:validation_failure</span>
<span class="vi">@message</span> <span class="o">=</span> <span class="s1">'Validation of params failed'</span>
<span class="vi">@description</span> <span class="o">=</span> <span class="s1">'The server could not validate the parameters present with the request. Please check the validation_errors key (hash) for more details.'</span>
<span class="vi">@user</span> <span class="o">=</span> <span class="n">user</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">response</span>
<span class="k">super</span><span class="p">.</span><span class="nf">merge</span><span class="p">({</span> <span class="ss">validation_errors: </span><span class="vi">@user</span><span class="p">.</span><span class="nf">errors</span> <span class="p">})</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<h2 id="conclusion">Conclusion</h2>
<p>I’ve used variants of this pattern multiple times over the years, and find it a <em>clean</em> way to handle <em>exceptional</em> situations that require a simple response to indicate failure. To see this pattern in action in a project, check out <a href="https://github.com/godreams/admin-server">GoDreams Admin Server</a>.</p>I want to share a pattern that I’ve repeated multiple times in the past when developing API-s with Rails, which grants the ability to respond to invalid requests with a standardized message format by raising an exception.Mixing React with jQuery2016-12-29T00:00:00+05:302016-12-29T00:00:00+05:30https://blog.harigopal.in/guides/mixing-react-with-jquery<p>For the past two weeks, I’ve been merrily mixing jQuery into my React components, and I have a few gotchas to share. jQuery certainly needs no introduction, but if you’re new to React, check out <a href="https://facebook.github.io/react">Facebook’s <em>excellent</em> documentation on it</a>, and try building something with it - it’s a peek into the future!</p>
<h2 id="why-even-do-that">Why even do that?</h2>
<p>Mixing jQuery with React <em>felt wrong</em> when I first considered it. After all, one of the prime purposes of using React is to escape from the spaghetti-code-hell that can arise when creating complex interfaces with lots of different interactions.</p>
<p>The thing is, however, that <em>that</em> hell is not of jQuery’s making. So the better question is <em>why not?</em> jQuery is the default JS library available to you if you work with Rails (like I do), and it makes working with JavaScript much easier.</p>
<h2 id="its-all-about-the-state">It’s all about the state</h2>
<p>The main issue you’ll encounter if you add jQuery to a React component is unexpected interactions with React’s state-based renderer. In most cases, this means issues with modifications to the DOM, made by jQuery, that React isn’t aware of.</p>
<h3 id="a-problematic-scenario">A problematic scenario</h3>
<p>Let’s take the case of using your friendly neighborhood datepicker inside a component.</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ExerciseRecord</span> <span class="kd">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">Component</span> <span class="p">{</span>
<span class="nx">componentDidMount</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">.js-date-input</span><span class="dl">'</span><span class="p">).</span><span class="nx">myFavDatePicker</span><span class="p">();</span>
<span class="p">}</span>
<span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span>
<span class="p"><</span><span class="nt">form</span> <span class="na">onSubmit</span><span class="p">=</span><span class="si">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">handleSubmit</span> <span class="si">}</span><span class="p">></span>
<span class="si">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">exercises</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">exercise</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span>
<span class="p"><</span><span class="nt">div</span><span class="p">></span>
<span class="p"><</span><span class="nt">label</span><span class="p">></span><span class="si">{</span> <span class="nx">exercise</span> <span class="si">}</span> done on<span class="p"></</span><span class="nt">label</span><span class="p">></span>
<span class="p"><</span><span class="nt">input</span> <span class="na">className</span><span class="p">=</span><span class="s">'js-date-input'</span>
<span class="na">name</span><span class="p">=</span><span class="si">{</span> <span class="dl">"</span><span class="s2">dates[</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">exercise</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">]</span><span class="dl">"</span> <span class="si">}</span><span class="p">/></span>
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p"><</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"submit"</span><span class="p">/></span>
<span class="p"><</span><span class="err">/</span><span class="na">form</span><span class="p">></span>
);
}
}
</code></pre></div></div>
<p>The problem above is that jQuery code doesn’t account for changes made by React, which means that the datepickers are initialized only once. Any modification of <code class="language-plaintext highlighter-rouge">this.props.exercises</code> (from a parent component) that causes a re-render of this component would introduce new fields without an active datepicker.</p>
<h3 id="the-fix-extract-and-control">The fix: Extract and control</h3>
<p>I see two possible fixes for this situation:</p>
<ol>
<li>The simplest fix would be to use <code class="language-plaintext highlighter-rouge">componentDidUpdate</code> to initialize datepickers on all updates.</li>
<li>Extract the responsibility to a new <code class="language-plaintext highlighter-rouge">DateInput</code> component.</li>
</ol>
<p>Repeated initializations could cause issues with the datepicker, so my preferred approach would be to perform an extraction:</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">DateInput</span> <span class="kd">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">component</span> <span class="p">{</span>
<span class="nx">componentDidMount</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">.js-date-input-</span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">key</span><span class="p">).</span><span class="nx">myFavDatePicker</span><span class="p">();</span>
<span class="p">}</span>
<span class="nx">handleChange</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(</span><span class="nx">date</span><span class="p">:</span> <span class="nx">$</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">).</span><span class="nx">val</span><span class="p">());</span>
<span class="c1">// and maybe pass it back up the chain?</span>
<span class="p">}</span>
<span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span>
<span class="p"><</span><span class="nt">input</span> <span class="na">className</span><span class="p">=</span><span class="si">{</span> <span class="dl">'</span><span class="s1">js-date-input-</span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">key</span> <span class="si">}</span>
<span class="na">onChange</span><span class="p">=</span><span class="si">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">handleChange</span> <span class="si">}</span><span class="p">/></span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Note how I’ve used the <code class="language-plaintext highlighter-rouge">key</code> prop to uniquely identify the input. The <code class="language-plaintext highlighter-rouge">key</code> can serve another purpose, which I’ll discuss in a bit.</p>
<h2 id="clean-up-after-yourself">Clean-up after yourself</h2>
<p>In the above example, we’ve created a component to manage creation and updation of the datepicker element. We should go one step further and ensure that the component can also manage its own destruction.</p>
<p>jQuery libraries often modify or introduce new elements into the DOM, which is often placed at the bottom of <code class="language-plaintext highlighter-rouge"><body></code>, placing it outside the React container. If the React component is unmounted, this leaves open the very real possibility that it’ll leave behind junk in the DOM. Cleaning up after yourself should be simple if the library supports it (most do):</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">DateInput</span> <span class="kd">extends</span> <span class="nx">React</span><span class="p">.</span><span class="nx">component</span> <span class="p">{</span>
<span class="nx">componentWillUnmount</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">.js-date-input-</span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">key</span><span class="p">).</span><span class="nx">myFavDatePicker</span><span class="p">(</span><span class="dl">'</span><span class="s1">destroy</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">...</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="using-key-to-regenerate-components">Using <em>key</em> to regenerate components</h2>
<p>In rare cases, direct manipulations of the DOM from jQuery can lead to a situation which renders React unable to update the component. In such situations, it’s up to you to alter the <code class="language-plaintext highlighter-rouge">key</code> prop passed to the component.</p>
<p>Updating <code class="language-plaintext highlighter-rouge">key</code> instructs React to discard the previous component and create a new one. This gives you a pristine component to work with. In such situations it might be wise to ponder whether a more conventional solution can be had by employing clever(er) coding.</p>
<h2 id="communication-with-the-jquery-world-outside">Communication with the jQuery world outside</h2>
<p>If you’re like me, then you’re probably introducing React components into an existing project (that uses jQuery), instead of building a entirely React-based application. So unless your component is trivial, you’ll need a good way to let the jQuery-driven world outside communicate with the React (root) component.</p>
<p>React’s <a href="https://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html">Top Level API</a> makes this super easy. Use <code class="language-plaintext highlighter-rouge">ReactDOM.render</code> to create or update existing components, and <code class="language-plaintext highlighter-rouge">ReactDOM.unmountComponentAtNode</code> to destroy existing ones.</p>
<p>Whichever you pick, <strong>do not</strong> do what I did the first time; <code class="language-plaintext highlighter-rouge">$('.react-container'').html('')</code> will leave behind loaded React components in memory. Ouch.</p>
<h2 id="server-side-rendering-is-a-no-go">Server-side rendering is a no-go</h2>
<p>A lot of jQuery code simply won’t execute without <code class="language-plaintext highlighter-rouge">window</code> being available - which it isn’t on the server. So if you want to render server-side you’ll have to avoid using jQuery for initial render of all components, which can be pretty tricky.</p>
<h2 id="wrap-up">Wrap-up</h2>
<p>The bottom line is that jQuery is beloved by many, and if using jQuery makes adopting React more palatable then by all means, mix and enjoy. But as the saying goes, <em>enjoy responsibly</em> - keeping the quirks and drawbacks in mind will let you combine the best of both worlds. Cheers!</p>For the past two weeks, I’ve been merrily mixing jQuery into my React components, and I have a few gotchas to share. jQuery certainly needs no introduction, but if you’re new to React, check out Facebook’s excellent documentation on it, and try building something with it - it’s a peek into the future!The next step2016-12-18T00:00:00+05:302016-12-18T00:00:00+05:30https://blog.harigopal.in/blogging/the-next-step<p><strong>Objective:</strong> I’m going to post my thoughts on the programming-related topics - whether they are interesting tidbits from my day-to-day work, ideas that I’ve encountered in my wanderings across the web, or things that I’ve learned from conversations with friends. This won’t be easy, but then good things rarely are.</p>Objective: I’m going to post my thoughts on the programming-related topics - whether they are interesting tidbits from my day-to-day work, ideas that I’ve encountered in my wanderings across the web, or things that I’ve learned from conversations with friends. This won’t be easy, but then good things rarely are.