Having a firm understanding of the various architectural formats allow designers to build innovative, reactive, and resilient applications to scale. As such, following these industry-vetted standards can save time, ensure reliability, and drive results. After all, why should businesses spend time and resources reinventing the wheel?
But mere acquaintance with the different architectures like CRUD-based architecture, Microservices-based architecture, and event sourcing-based architecture will just not be enough to make a well-rounded decision regarding it. One needs to dive into the details and understand the nature, applicability, and value offered by each of them.
In this post, we are taking a look at CRUD and event sourcing architectures, with a view of why one should consider porting from the former to the latter. Let’s take a look.
What Is CRUD?
CRUD is an acronym for Create, Read, Update, and Delete. It constitutes these four database commands, which are rather self-explanatory on their own, that are deemed as necessary for persistent storage management. This pattern is widely used by businesses across sectors and industries for tracking customer data, employee information, payment records, accounts, etc.
Let us quickly illustrate the regular flow of events in the case of CRUD:
Gary is browsing through an eCommerce website. He adds a gaming console, one controller, and a game to his cart. At that point in time, the cart database will look somewhat like this:
Suppose he were to add another item (say, a headset) to the cart. The database updates to:
If Gary removes the headset, the table reverts to the one previously displayed. Additionally, if he were to add another controller, the database would be as follows:
In essence, the database follows the Create – Read – Update – Delete approach to maintaining the table. The “update” and “delete” functions are characteristics of CRUD.
Limitations of the CRUD Approach
While the CRUD approach is highly preferred due to the lightweight and simplistic nature of its operations, it is plagued by its own set of limitations. These include:
The first and most common criticism of CRUD is that it is primitive and obsolete. Rather than viewing it as architecture or design, it is seen as a cycle of steps that can be followed, whether one builds a database or an API.
CRUD relies on the permanence of states in a database. However, the storage of such information can be wasteful and resource-intensive, given the dynamic nature of events surrounding data manipulation in the current landscape.
Even though the CRUD architecture is simple, it requires heavy investment in terms of code and effort at the initial stages. Despite that, CRUD fails to performly competently when it comes to cloud load balancing.
While the CRUD code may be quite straightforward in the beginning, the moment it begins to share data with other services or microservices, problems will arise relating to the synchronization of states and handling failures.
The complexities involved in the CRUD architecture will call for equally intricate solutions, which could extend to failure tracking, manual state logs, asynchronous batch processing, and more. Such considerations would be tougher to code and integrate.
In CRUD models, entity instances are typically represented dually and as a mutable object in memory occupying relation a mutable row in a al database table. Such a structure results in the infamous object-relational impedance mismatch. Even the attempt to bridge such divides will further inject complications into the architecture.
What Is Event Sourcing Architecture?
Event Sourcing is a data storage technique that is seen as an upgrade of CRUD. It merely focuses on the Create and Read functions and completely omits the Update and Delete actions for values, as would be the case in CRUD. In simpler words, you cannot perform destructive operations through event sourcing.
So then, how does it overcome the challenges faced by CRUD?
Here’s where it gets interesting: the traditional approach followed by CRUD, an event sourcing stores the individual changes to the record as a series of deltas leading to the current state as a factor of time rather than persisting on the current state itself. In this manner, event sourcing imparts traceability to state changes. In most cases, this functionality is often combined with Domain-Driven Design (DDD) and Command Query Responsibility Segregation (CQRS) design patterns.
To better understand event sourcing architecture, let us fall back to Gary’s example. Since Gary adds a gaming console, one controller, a game, and a headset to his cart, the cart lifecycle will be depicted as follows:
Looks pretty much like the cart database for the CRUD architecture, right? But suppose Gary were to add another controller to his cart, the cart would now be:
Notice the difference? The request for adding another item to the cart is viewed as a separate event rather than an update to the existing database. Feel free to scroll up and see what the cart looked like under CRUD.
Now, let’s say that Gary changed his mind about the headset and removed it from his cart. Here’s how the change will be put into effect:
Once again, rather than updating or deleting information, event sourcing has created a record of the event. Suppose Gary is finally happy with his cart and checks out, the final cart lifecycle would be as follows:
By tracing the events that take place over time, one can easily compute that Gary added a gaming console, added a controller, added a game, added a headset, added another controller, removed the headset, and checked out. As such, he purchased one gaming console, two controllers, and one game. This sequential process of restoration of states and tracing back the events is called replay.
Hence, it becomes clearer that event sourcing is a log of all the changes in events arising from customer activities.
Benefits of Adopting the Event Sourcing Architecture
From a basic understanding of event sourcing, it appears to be a better and more improved alternative that overcomes the drawbacks of CRUD. To emphasize this fact, let us take a look at the proven advantages of event sourcing.
Event sourcing follows an event-driven architecture and facilitates the reliable publication of events upon a state change. Hence, it is more fact-oriented than its CRUD counterpart.
It overcomes the object-relational impedance mismatch problems, as seen with CRUD, by persisting events rather than domain objects. The final state of the domain object can be computed easily by replaying events chronologically.
It maintains a record of the series of events, which can be manipulated in the append-only state. By eliminating the need for tracking the states and the relationship between entities, the event sourcing code is easier to write and read from the database.
Since it keeps a log of how an entity reached its current events, event sourcing maintains consistency between audit data and transactional data as they are both the same. Further, it is also an excellent fail-safety as data can be reconstituted from the event log.
As all events are merely appended to the existing database and the update and delete functionalities are revoked, event sourcing architecture focuses purely on the writing aspect, which improves its performance.
Event sourcing allows for the analysis of the event stream, which helps businesses in deriving crucial information from it. As such, they can gain a top-level view of all the system activities, without complicating the write function.
Architectures following the event source model are easier to test and debug as the commands and events can be simulated for testing before introducing them. Further, the event log also acts as an excellent record of the debugging activities and if an issue is detected, one can replay the event log in a controlled environment to understand the source of such anomalies.
It can store any type of message and any consumer can access this information as long as they possess the authorized access. It is possible to raise temporal queries to determine the state of an entity at any given time. As such, they are highly flexible.
Event-sourced applications are easier to migrate as opposed to their monolithic counterparts as they follow a microservice-based architecture. It is possible due to the loose coupling of business entities for exchange events.
As more applications need real-time data to be delivered in an ordered and asynchronous manner, there exists a growing demand for event sourcing. Further, it serves as an excellent medium to consume and manage the log data of an application on a web-scale. In such conditions, event sourcing establishes a single point of truth which advances the reliability of the application.
However, one must avoid viewing event Sourcing as the end-all, be-all solution to creating databases as it may only yield effect on a case-to-case basis. For instance, the example that we have used is pretty basic and even then, the Event Sourcing architecture appears to be more lengthy than its CRUD counterpart. This, in itself, highlights how Event Sourcing may not be as capable when it comes to complex or convoluted data management that involves several state changes.
In simpler words, while Event Sourcing architecture does enjoy a significant advantage over CRUD, database managers have to factor in project requirements and devise the best-suited approach. Only then would you be capable of harvesting the true benefits of either architecture.