Advanced Ruby on Rails Architecture Way (Part 2)
“I have not failed, I’ve just found 10,000 ways that won’t work”
Thomas Alva Edison
So here’s the second year of our RoR development path. A quick look at what we’ve already covered: services, commanders, presenters, query. In the second year, a number of issues are already resolved and the process moves smoothly. One day you get a feeling “I should rewrite everything” and you start paying attention to more serious architectural decisions. So you come to:
Firstly, let’s find out what is it?
Trailblazer is a high-level architecture for web applications, not just for Rails. It gives you a high-level architecture, extends the basic MVC pattern with new abstractions. Trailblazer gently enforces encapsulation, an intuitive code structure and gives you an object-oriented architecture. Well, Trailblazer is all about structure. It helps re-organize existing code into smaller components where different concerns are handled in separated classes, so you can pick which layers you want. Trailblazer completely pulls the business out of the framework so that there is only HTTP and nothing more. It doesn’t impose technical implementations, it offers mature solutions for recurring problems in all types of Rails applications.
The author of Trailblazer is Nick Sutterer, on the Internet known as @apotonick. Those who have already felt the pain of fast-growing projects, realize what idea Nick tries to bring to us all.
“Nick visited Lviv (Ukraine) and was a speaker at Pivorak. He’s really talkative, funny and cool man, we spent awesome time together”- Volodya Sveredyuk
In Trailblazer everything moves around the operations: the contact with models get permits thus validate data through contact. Another thing that we really like is cells, very cool view layer for Rails. In Cells, you work with views as with Ruby objects that can render one little template and that’s it. You have no global state, as all methods for object definition are available in this template. Actually, this is very similar to React. We leave the link on React, so you can compare.
Some operations of the Trailblazer’s work:
In Trailblazer everything is resolved around the steps, these steps are used without Ifs. You declare steps, Trailblazer searches for the methods in this object and execute them. For example, if you have “false” returned, then it is a bad step failure. The whole operation, which we’ve creates as an object always gives us a result. That is, we can explain all business logic without Ifs.
Another positive thing about Trailblazer is the change of concepts.
Concepts are something like domain objects. When your application is growing, it is still in parallel cluttered with a bunch of operations. In Trailblazer you have a button Concepts where the basic objects are held. Already inside every concept, you see what must be inside it. In this way, you better understand the architecture, what’s happening inside it, what can be also added.
Trailblazer 2 saw the world this year. It differs a bit from the first version. In version 2.1 of Trailblazer, the method called flow is added. It shows how to follow the whole operation, all the steps from the beginning. This greatly simplifies our life, because it is possible to track at what point something went wrong. Thus help to solve the issue faster and move further.
Over the time, on the third or fourth year in development everything comes down to a bad code and there’s nothing you can do about it, especially if you work alone on the project. Whatever architecture you have, it worths nothing if you don’t stick to the primarily chosen strategy.
There’s one book we highly recommend you to read “Domain Driven Design: Tackling Complexity in the Heart of Software” written by programmer Eric Evans and published in 2004.
DDD is the expansion upon and application of the domain concept, as it applies to the development of software. It aims to ease the creation of complex applications by connecting the related pieces of the software into an ever-evolving model. DDD focuses on three core principles:
- Focus on the core domain and domain logic.
- Base complex designs on models of the domain.
- Constantly collaborate with domain experts, in order to improve the application model and resolve any emerging domain-related issues.
Eric has successfully described why you should not put all goods you gather in one application. He described why you should study and understand the sphere you work in and then adapt the code to the sphere, not vice versa. Talking less, the book is complicated but very cool and worth reading.
And one more thing left for today — Microservices.
Microservices is a variant of the service-oriented architectural style that structures an application as a collection of loosely coupled services. The benefit of decomposing an application into different smaller services is that it improves modularity and makes the application easier to understand, develop and test. It also parallelizes development by enabling small autonomous teams to develop, deploy and scale their respective services independently. Microservices also allows the architecture of an individual service to emerge through continuous refactoring. Microservices-based architectures enable continuous delivery and deployment. You should never start your project with them. If you have gone back and forth through all routes of Ruby you’ll understand that there are cases when Ruby is not suitable. So you should write a service that solves the problem from the edges to the center.
AND final recommendation: always strive to remain flexible and fast, not cool!