From the fourth quarter of 2017 through the first half of 2018 I was almost exclusively creating Ruby on Rails applications. After the excitement of mastering a new toolset wore off, I started to feel that I was working on a dated platform. There’s nothing inherently bad about Ruby on Rails, it is a time-tested and validated approach for creating reliable monolithic web applications. But, having just previously worked at a shop where we figured out how to build actual microservices, building monolithic applications simply felt dated.
I certainly wasn’t going to use microservices out of the gate for my side projects, but I at least wanted to abstract the presentation layer from the data access layer. So, I needed a set of tools which made creating SPAs (single page applications) and APIs as easily as it was to create views and models with Rails. Where I landed isn’t quite as easy, but it is fairly enjoyable, and I really don’t even know what I’m doing yet. The stack I landed on was Elm for the front end and, for now, FeathersJS for the backend.
On one hand, I don’t expect people who have only worked on monolithic applications to completely understand why I feel the need to split the code base. On the other hand, I’ve seen what happens when a monolithic development shop is asked to make an app work on mobile. In the best case scenario, their monolithic application has a responsive user interface and the client doesn’t need any off-line capabilities. As soon as the client needs off-line capabilities a SPA is probably required, unless the client is ready to spend for native app development. The reality is that web application development has become intertwined with mobile application development. Established shops like Basecamp can implement a native-heavy hybrid mobile strategy, but that strategy may not be best for a shop trying to quickly get market traction.
It may seem like I am picking on Ruby on Rails or DHH, that’s not my intent. I respect the Rails contributors and what they have created. Having created server-side web applications using Python (Django), PHP (Cake, Laravel), and even ColdFusion, I think Ruby on Rails is best in-class. (I’m ignoring enterprise class platforms which have a different set of constraints and objectives.) I’m using Rails as my example because it’s harder to dismiss my core argument about the datedness of monolithic applications by blaming the toolset.
The package system for the language is getting better. But, it’s hard to forget the time that one developer pulled packages from npm and prevented everyone from deploying for a day. Ohh, there’s also the lack of a standard library which made everyone dependent upon a library that just left-pads strings.
I really want something that allows me to write fewer tests. My agile friends and colleagues will gasp at that, but tests are overhead. I see tests in the same light as scaffolding – a necessary evil. I don’t write tests for the business value, because they provide none. I don’t write tests for fun, because it isn’t. I write tests to make refactoring the application easier. A statically typed language with an intelligent compiler should reduce the need for many classes of tests. A functional language would reduce the need even further.
After searching and trying a lot of front-end web technologies, I decided to invest time in learning Elm. I was skeptical, but it most closely matched my desired requirements. I started by following the guides and then evolved that application into a score keeping app. Everything was going well with the single page, so I added a router to created a more useful single page application.
To get the two pieces talking to each other requires getting a better understanding of the Elm architecture, but it wasn’t too difficult. The hardest part was setting up the JSON decoding pipeline inside of Elm. Some of the difficulty was simply due to the nature of adding type information to the JSON data. Some of the difficulty was due to the awkwardness of the patterns Elm uses for decoding.
Unfortunately, since I started writing this post elm has been updated from 0.18 to 0.19. I would update my example code to use the latest version, but it uses sockets and elm 0.19 currently lacks support for websockets. There’s nothing inherently wrong with this demo using elm 0.18, but there have been some significant changes, so not all the code there applies in an elm 0.19 environment.
Besides for unexpectedly loosing websocekts, I have enjoyed using elm. Ruby on Rails developers will appreciate the enjoyment factor, since their platform is at least partially driven by developer happiness. So, if you are a Rails developer who feels like they are getting left behind the times, maybe give elm a try.