Is Rails a good fit for writing rich frontend applications?

This is a question I’ve asked myself months ago, working as a consultant for a client with a quite unique app.

Does it make sense to stick with Rails? Maybe it’s a good time to drop it?

Ruby on Rails worked well in the app for quite a while. It was enterprise system for a rather interesting clients: They were accustomed to desktop-like experience of their tools. They were using classic spreadsheets software like Microsoft Excel back then. This was the first project I’ve worked on where the particular way of how user interface works was the real business requirement.

When I started working on that project, we were far away from the ideal user experience. In fact, it was a simple Rails application, with HTML views being rendered on the backend with some data tables.

I (and, of course, the rest of my team) needed to find a way to implement new features, maintain the codebase and avoid regressions and find a way to achieve this desktop-like behavior of an app. Not to mention the domain was absolutely crazy in terms of complexity and we were having a client which were taught to talk CRUD. It was quite tough to cope with this challenge!

One of our first decisions when working with this app was to stop serving HTML from the backend and build UI on the client side with JavaScript. We knew that if we’d ever want to achieve our desktop experience, it was a way to go. We’ve got quite a nice expertise from working in previous projects (for me it was writing highly interactive games working in the browser) so we were quite comfortable with this process. So we’ve started working, writing features and replacing static HTML views + jQuery with apps (in a hexagonal sense). It was actually quite challenging since the app was big and we were struggling with our tooling. We’ve discovered React this way and it’s such a great fit in our toolbox that we’re specializing in it now ;).

But there was still a major problem. While we were experienced both with JS and Rails, we were still creating our Rails backend in a way that was slowing us down. This was the time when I was struggling with answering “yes” to the question on the subject.

The problem is, Rails is great in what it does - which is writing apps with views served by the backend. It, of course, has great tools to write code which only serves data which can be consumed by JS. But still, there were bigger problems which came with convention.

With sequential IDs generated by default in Rails we were tightly bound to our backend - every action which will be eventually saved needed to be consulted with backend right away. It was a problem since it was introducing problems like slowness of feedback for an user - every saved resource, most clicks on buttons was calling backend to make the result. Of course, we’d be able to work without backend - but the resulting code was messy and sprinkled with conditionals about things being persisted or not.

We’ve found the solution to this problem by introducing UUIDs. This way we were able to do much more on the frontend without consulting our results with the backend all the time. What’s more, by using UUIDs and passing them in our POST/PUT/DELETE calls we were able to simplify our Rails backend even more, by not reading responses after every change. Without being bound to the backend, we were a little step closer to work in a very similar way desktop app works ;).

There were many different fundamental problems in Rails conventions we needed to solve to achieve desktop-like experience (you should aim for it too in your apps!) and boost productivity while working on our app. UUID was the first fundamental change. We also needed to get rid of Sprockets limitations (to have a proper modularization of our JS code), include real-time updates to our JS front-end and much more.

The result was spectacular. After months of hard work (it was a big, legacy app) the client came back to us saying that potential buyers were shocked about how good the experience is. This was a moment of a real joy to our team - we succeeded with the task. I wish you the same feelings we had back then.

During these months, and to this date I was collecting such gems of knowledge which needed a lot of groundwork to research and implement correctly. Those techniques I’ve learned helped me to write dynamic, rich code better and find the answer to the question of Rails being a good fit. And my answer is:

Yes. But you need to be aware of what you need to change to make it work in an optimal way.

Frontend-friendly Rails

I’ve hand-picked the most useful techniques I’ve learned and decided to write a book about it. Those are techniques used today in every app we’re writing and needs a dynamic user interface. Some of them are coming from my colleagues in Arkency (so, unfortunately, I’m not that smart :() and I’ve decided to describe them in this book. It is called Frontend-friendly Rails - because this book is all about connecting frontend and Rails backend in the most optimal way. By implementing those techniques your Rails backend can be friendly and not stand in a way when you’re implementing your rich JS UI.

The book is (almost, some editorial work needed) already finished, so I got a list of techniques described in the book.

Switch your Rails application to frontend-generated UUIDs.

This process comes with many benefits, allowing your frontend to be free in terms of consulting with the backend. It allows you to write certain advanced backend communication techniques (like auto-save, for example) in a way easier way than with sequential IDs. But there are certain technological changes: For example how to do it in an unobtrusive way, or how to ensure UUID will be generated if not provided by the frontend. I describe the whole process of transforming your model to be UUID-based, without losing data and in a database-agnostic way.

Setup the Cross-Origin Resource Sharing.

This is a challenge often overlooked when the team decides to go to the higher level with their frontend - which is separating it completely from Rails. I describe how to setup it - and why we’re having this problem in the first place.

Prepare JSON API endpoints for your API.

A well-thought format of API responses can make your API easier to use by your frontend and third parties, not to mention extendability. JSON API is a great standard of responses, so you do not need to reinvent the wheel. I describe the process of introducing JSON API-compliant responses to your controllers in a way that is not touching your old API endpoints (if you have any) at all. This makes it a way safer way for legacy applications.

Create a living API - beyond request-response cycle.

This technique is all about making your frontend even more interactive - by introducing live updates so you can see what other users are editing in your application in real-time. I describe how to do it using Pusher library since I have the biggest experience with this tool - but the mechanism is the same with any other tool. I also describe how to make such mechanism non-distinguishable from the current user actions, resulting in a way easier maintenance of such code.

Consequences of frontend decisions.

This is not a technique, but more like a philosophical essay ;). I deconstruct the thinking behind two basic flows of how frontend app may work - bound to the backend or not bound to it - code snippets included. Knowing those differences allowed me to upgrade my thinking about JS frontends to the higher level.

Using modern Javascript with Rails. Quick guide to tooling in JavaScript. Constructing the Node.js assets pipeline - step by step.

Those three chapters are in fact connected together. The biggest boost of productivity that you can have while writing your frontend app is switching to modern JavaScript tooling and standards. Using tools like Webpack to achieve modularization of your code, or Babel to use the newest flavor of JavaScript are bringing spectacular productivity gains. In this part I show why it is beneficial to you, what new tools you’ll be using and what they do and how to build the whole JS assets pipeline which replaces Sprockets - step by step. By finishing this chapter and following steps you’ll have working assets stack with production-ready builds, ES2015 and CoffeeScript support and a complete testing stack. I find this knowledge extremely helpful and most of our projects have this knowledge applied.

I’ve also included a handful of blogposts we’ve written about making Rails more friendly while working with rich frontends in a form of bonus chapters. I’m very happy about contents of this book and had tons of fun writing it - and I’m sure it’ll make you a better frontend developer.

(this announcement was initially sent to the Arkency mailing list - the place where all our announcements go first. If you’d like to know early about what we’re cooking at Arkency, please subscribe)