Dementyev | Layered Design for Ruby on Rails Applications | E-Book | sack.de
E-Book

E-Book, Englisch, 298 Seiten

Dementyev Layered Design for Ruby on Rails Applications

Discover practical design patterns for maintainable web applications
1. Auflage 2023
ISBN: 978-1-80181-243-6
Verlag: De Gruyter
Format: EPUB
Kopierschutz: 0 - No protection

Discover practical design patterns for maintainable web applications

E-Book, Englisch, 298 Seiten

ISBN: 978-1-80181-243-6
Verlag: De Gruyter
Format: EPUB
Kopierschutz: 0 - No protection



No detailed description available for "Layered Design for Ruby on Rails Applications".

Dementyev Layered Design for Ruby on Rails Applications jetzt bestellen!

Autoren/Hrsg.


Weitere Infos & Material


Table of Contents - Rails as a Web Application Framework
- Active Models and Records
- More Adapters, Less Implementations
- Rails Anti-Patterns?
- When Rails Abstractions Are Not Enough
- Data Layer Abstractions
- Handling User Input outside of Models
- Pulling Out the Representation Layer
- Authorization Models and Layers
- Crafting the Notifications Layer
- Better Abstractions for HTML Views
- Configuration as a First-Class Application Citizen
- Cross-Layers and Off-Layers


1
Rails as a Web Application Framework
Ruby on Rails is one of the most popular tools to build web applications, which is a huge class of software. In this chapter, we will talk about what makes this class different from other programs. First, we will learn about the HTTP request-response model and how it can naturally lead to a layered architecture. We will see which layers and HTTP components Ruby on Rails includes out of the box. Then, we will discuss the off-request processing layer, background jobs, and the persistence layer (databases). In this chapter, we will cover the following topics: The journey of a click through Rails abstraction layers Beyond requests – background and scheduled tasks The heart of a web application – the database By the end of this chapter, you’ll have a better understanding of the core web application principles and how they affect Rails application design. You will learn about the main Rails components and how they build up the basic abstraction layers of the application. These fundamental ideas will help you to identify and extract abstractions that better fit natural web application flows, thus leading to less conceptual overhead and a better developer experience. Technical requirements
In this chapter and all chapters of this book, the code given in code blocks is designed to be executed on Ruby 3.2 and, where applicable, using Rails 7. Many of the code examples will work on earlier versions of the aforementioned software. You will find the code files on GitHub at https://github.com/PacktPublishing/Layered-Design-for-Ruby-on-Rails-Applications/tree/main/Chapter01. The journey of a click through Rails abstraction layers
The primary goal of any web application is to serve web requests, where web implies communicating over the internet and request refers to data that must be processed and acknowledged by a server. A simple task such as clicking on a link and opening a web page in a browser, which we perform hundreds of times every day, consists of dozens of steps, from resolving the IP address of a target service to displaying the response to the user. In the modern world, every request passes through multiple intermediate servers (proxies, load balancers, content delivery networks (CDNs), and so on). For this chapter, the following simplified diagram will be enough to visualize the journey of a click in the context of a Rails app. Figure 1.1 – A simplified diagram of a journey of the click (the Rails version) The Rails part of this journey starts in a so-called web server – for example, Puma (https://github.com/puma/puma). It takes care of handling connections, transforming HTTP requests into a Ruby-friendly format, calling our Rails application, and sending the result back over the HTTP connection. Communication models Web applications can use other communication models, and not only the request-response one. Streaming and asynchronous (for example, WebSocket) models are not rare guests in modern Rails applications, especially after the addition of Hotwire (https://hotwired.dev/) to the stack. However, they usually play a secondary role, and most applications are still designed with the request-response model in mind. That’s why we only consider this model in this book. Next, we will take a deeper look at the right part of the diagram in Figure 1.1. Getting to know the basics of request processing in Rails will help us to think in abstraction layers when designing our application. But first, we need to explain why layered architecture makes sense to web applications at all. From web requests to abstraction layers
The life cycle of a web application consists of the bootstrap phase (configuration and initialization) and the serving phase. The bootstrap phase includes loading the application code, and initializing and configuring the framework components – that is, everything we need to do before accepting the first web request – before we enter the serving phase. In the serving phase, the application acts as an executor, performing many independent units of work – handling web requests. Independent here means that every request is self-contained, and the way we process it (from a code point of view) doesn’t depend on previous or concurrent requests. This means that requests do not share a lot of state. In Ruby terms, when processing a request, we create many disposable objects, whose lifetimes are bound by the request’s lifetime. How does this affect our application design? Since requests are independent, the serving phase could be seen as a conveyor-belt assembly line – we put request data (raw material) on the belt, pass it through multiple workstations, and get the response box at the end. A natural reflection of this idea in application design would be the extraction of abstraction layers (workstations) and chaining them together to build a processing line. This process could also be called layering. Just like how assembly lines increase production efficiency in real life, architecture patterns improve software quality. In this book, we will discuss the layered architecture pattern, which is generic enough to fit many applications, especially Ruby on Rails ones. What are the properties of a good abstraction layer? We will try to find the answer to this question throughout the book using examples; however, we can list some basic properties right away: An abstraction should have a single responsibility. However, the responsibilities themselves can be broad but should not overlap (thus, following the separation of concerns principle). Layers should be loosely coupled and have no circular or reverse dependencies. If we draw the request processing flow from top to bottom, the inter-layer connectors should never go up, and we should try to minimize the number of connections between layers. A physical assembly line is an example of perfect layering – every workstation (layer) has, at most, one workstation above and, at most, one below. Abstractions should not leak their internals. The main idea of extracting an abstraction is to separate an interface from the implementation. Extracting a common interface can be a challenging task by itself, but it always pays off in the long term. It should be possible to test abstractions in isolation. This item is usually a result of all the preceding, but it makes sense to pay attention to it explicitly, since thinking about testability can help us to come up with a better interface. From a developer’s perspective, a good abstraction layer provides a clear interface to solve a common problem and is easy to refactor, debug, and test. A clear interface can be translated as one with the least possible conceptual overhead or just one that is simple. Designing simple abstractions is a difficult task; that’s why you may hear that introducing abstractions makes working with the code base more complicated. The goal of this book is to teach you how to avoid this pitfall and learn how to design good abstractions. How many abstraction layers are nice to have? The short answer is, it depends. Let’s continue our assembly line analogy. The number of workstations grows as the assembly process becomes more sophisticated. We can also split existing stages into multiple new ones to make the process more efficient, and to assemble faster. Similarly, the number of abstraction layers increases with the evolution of a project’s business logic and the code base growth. In real life, the efficiency metric is speed; in software development, it is also speed – the speed of shipping new features. This metric depends on many factors, many of which are not related to how we write our code. From the code perspective, the main factor is maintainability – how easy it is to add new features and introduce changes to the existing ones (including fixing bugs). Applying software design patterns and extracting abstraction layers are the two main tools to keep maintainability high. Does it mean the more abstractions we have the more maintainable our code is? Surely not. No one builds a car assembly line consisting of thousands of workstations by the number of individual nuts and screws, right? So, should we software engineers avoid introducing new abstractions just for the sake of introducing new abstractions? Of course not! Overengineering is not a made-up problem; it does exist. Adding a new abstraction should be evaluated. We will learn some techniques when we start discussing particular abstraction layers later in this book. Now, let’s move on...


Dementyev Vladimir:
Vladimir Dementyev has been working on web applications for more than 10 years and launched his first Ruby on Rails project back in 2014. Since then, he has been working on a dozen of Rails web applications, used by hundreds of millions of customers, monolithic or component-based, following the Rails way or trying to swim against the current. He has been an active member of Rails open-source community since 2015, becoming a regular Rails contributor, a RailsConf speaker, and the author of dozens of gems, including AnyCable, TestProf, and Action Policy to name a few. For his work on the Ruby Next project, the author got the Fukuoka Ruby Award for outstanding performance in 2021. Currently, he's leading the backend developers' team at Evil Martians, helping dozens of web projects around the world build better software.



Ihre Fragen, Wünsche oder Anmerkungen
Vorname*
Nachname*
Ihre E-Mail-Adresse*
Kundennr.
Ihre Nachricht*
Lediglich mit * gekennzeichnete Felder sind Pflichtfelder.
Wenn Sie die im Kontaktformular eingegebenen Daten durch Klick auf den nachfolgenden Button übersenden, erklären Sie sich damit einverstanden, dass wir Ihr Angaben für die Beantwortung Ihrer Anfrage verwenden. Selbstverständlich werden Ihre Daten vertraulich behandelt und nicht an Dritte weitergegeben. Sie können der Verwendung Ihrer Daten jederzeit widersprechen. Das Datenhandling bei Sack Fachmedien erklären wir Ihnen in unserer Datenschutzerklärung.