Development
Ruby on Rails vs. Single-Page Applications (React)
February 17, 2020LLT Group
The Model-View-Controller (MVC) application architecture was popularized for web development nearly fifteen years ago. Since then, we have devised a lot of new ways to structure our applications. There are so many of these architecture choices now – Model-View-ViewModel, Hexagonal Architecture, Clean Architecture, and the list goes on – that choosing which to use is a difficult task. As a result, most software choices are based on (1) what is the newest technology, or (2) what the developers are most familiar with, not what is the best tool for the job. One of the newest and most popular architectures is the Single-Page-Application architecture (SPA), where all of the HTML generating code is written in JavaScript, using a tool like React or Vue.JS, and run on the browser. While SPA’s are good for some circumstances, I’ve worked on several that would have been easier to write as an MVC application. But the web world moves pretty fast, and something from 2007 is hard to argue for in 2020. Still, I believe that many web applications can be built most easily with an MVC framework. This means fewer bugs, faster development, and happier developers. So let’s look at why you should choose one software architecture over another in general, and why you should strongly consider MVC for your next project.
To start, what is software architecture? How can it help a code base, and when is it useful? Take this simple script:
We could add more architecture to this program by writing an abstract class, Operation, and a subclass for +, -, *, and /. The operations could live in their own module, and each class could live in its own file in a separate subdirectory. However, this would clearly make the program harder to understand, not easier.
Conversely, let’s imagine we were to write a complex web application like we did this script. In our application we have to read from a database, connect to a remote API, generate HTML, and log user data. And we’re writing all of this in one file! The program would be impossible to understand, and difficult to update. If we put all of the database code in its own file, all of the HTML code in its own file, etc. it becomes much easier to manage. We can go further. For example, if we have a lot of different pages, we might put all of the HTML generating code in a folder and each page in its own file within that folder.
Let’s synthesize this thinking into some definitions and conclusions:
- Architecture is the structuring of a program into different modules, classes, folders, files, functions, etc. A program has more architecture if it has wider usage and deeper nesting of this structuring.
- An architecture, such as MVC, is a particular way of structuring a program.
- The amount of architecture that a program calls for is proportional to the program’s complexity and size. In other words, our architecture should be as simple as possible while allowing our code base to be organized and well designed.
- It is good to structure a program based on its concerns, e.g. working with a database and displaying HTML.
- The code dealing with each concern should in turn be architected proportionally to its complexity and size. If the HTML display code in a web application is only 100 lines, it should all live in one file. But if the database code totals over 100,000 lines, then it should have its own internal organization with its own subsystems.
MVC architecture splits the application into three main systems:
Following our early discussion, MVC is a good choice when these three systems are in balance in complexity and scope. If there’s no need to have a database in your application, or if you’re just serving a JSON API and not a full web page, then MVC might be overkill for your program. On the other hand, the structure that MVC gives you might not be enough to sufficiently organize your code base. For example, it’s a good MVC principle that views don’t directly depend on models. If you have very complex views which require a lot of data to render, this can become a problem, and you might want to consider an architecture like Model-View-ViewModel which better organizes this complexity.
As the internet has grown and more computing has moved off of desktops and onto the cloud, the View part of web applications has grown in scope. We now have full office suites, artistic software, and complex video games that run in native HTML 5/JS on the browser. Looking at how these kinds of applications would be constructed in MVC makes it clear that it does not offer enough structure for the view code:
Single-Page-Applications were invented to solve this problem. An SPA is best thought of as two separate programs, a client and a server, which communicate with each other. Here is one way that an SPA might be architected:
First, this has the flexibility to organize the view code better than MVC (the whole client application is the “view” code). Second, the SPA architecture is overall more complex than in MVC. There are more places that code could go, and more subsystems in our application. And most importantly, instead of having one application, there are two applications that communicate with each other asynchronously. As we noted earlier, this extra complexity either a good or bad thing depending on the scale of the view code. Third, domain code on the client is probably duplicating logic that also exists on the server. Say you’re writing a banking application. You might want your UI to prevent the user from over-drafting their checking account, but you definitely want the server to perform the same check before making the transaction. In MVC, both the view and the query could use the same model code for this, but in an SPA it will have to be written for both applications.
Here’s what we can say about the choice between MVC and SPA architecture:
- If the view code needs to be more complex than standard MVC tools can accommodate, SPA architecture can be a superior choice.
- If this is not true, then SPA architecture will increase the complexity of the application for no benefit.
- If you are writing an SPA, then you greatly benefit from using the same language on the client and server, because you can eliminate duplicate domain logic and data-modeling between the two application-halves. You could either use Node.JS to run JavaScript/TypeScript on the server, or use a transpiler like JSweet to write your client code (in this case Java) in your server language.
All of this discussion is abstract, and it’s clear that none of these principles have changed over the last decade. So MVC is, at least, still a useful tool in the toolbox. I won’t talk about whether individual MVC frameworks have been superseded over the last few years – that’s beyond the scope of this article. “OK, fine,” you say, “MVC is still worth looking into even though it’s a little old school. But what about my application? How do I know before my team starts writing code what we should choose for my project?” The first thing I’ll say is that just because you need to have interactive/dynamic UI elements on some of your pages, you can still use MVC. You can put Javascript in an MVC application to add dynamism to your UI. The main category of applications that are generally easiest written in MVC are data-driven, workflow-based applications. This includes e-commerce websites, any websites where the user is filling out a succession of forms, or even a blog. That’s because these applications usually don’t have large UI functionality needs over basic HTML, and most of the complexity is on the data side. In addition, to make these applications more “web-like” in an SPA, you have to add complexity by replicating browser functionality, like capturing and redirecting back-button events. Most applications that software developers write, in my experience, fall under this category, which is why MVC is my default recommendation for a project. Some examples of web applications that fall into this category are Doodle.com (a popular meeting scheduling website,) HealthCare.gov, and Shopify (a popular e-commerce platform).
Here are the cases I would recommend considering SPA over MVC. First, any application that involves generating complex content in the web browser. These applications will likely need UI code that rivals traditional desktop applications in scope, so SPA is a good fit for managing that complexity. Examples of this kind of application are office suites like Google Docs, UXPin.com (an in-browser UI prototyping program), and Vectr.com (an in-browser vector graphics editing program). Second, any application that has non-trivial client side functionality that relies on business logic. In this case, I think the best architecture is a Single-Page-Application that uses the same client and server language, as I discussed earlier.
To summarize, the architecture of your application should be complex enough that your code base is easy to understand and maintain. If the architecture is more complex than it needs to be, it makes the code base harder to understand and maintain. Single-page-applications written with a tool like React or Vue.JS are great for applications with rich client-side functionality and a large client-side code base. But for a web application that only need dynamic elements, such as forms that add or disable fields based on user input in previous fields, SPA is probably overkill, and MVC should be strongly considered, even in 2020.