The Data-Driven World We Live In
'Data is money'—you’ve probably heard this phrase before. It’s true; data is the most valuable asset in the world today. Companies like Google, Facebook, and Amazon have built their business models around data.
Applications, whether web or mobile, revolve around data: displaying it, processing it, and sending it to backends or external systems. The challenge lies in managing data efficiently to provide seamless user experiences. The ability to process and react to data in real-time is increasingly becoming a differentiator between good and great applications.
As businesses continue to scale, the need for real-time data processing and event-driven architecture is becoming more evident. Developers and architects must adapt to modern methodologies that enhance application performance, scalability, and user satisfaction.
A Brief History of Event-Driven Architecture
Event-driven architecture (EDA) has been around for decades. It gained prominence in distributed systems, especially in enterprise software, where decoupled communication was necessary. Early implementations appeared in messaging systems, like IBM MQ and Enterprise Service Buses (ESBs), allowing applications to communicate asynchronously.
With the rise of microservices and real-time applications, event-driven patterns became more popular. Modern frameworks, such as Apache Kafka, RabbitMQ, and cloud-based event buses, enable scalable event processing across various domains. In frontend development, this pattern evolved through state management libraries like Redux, RxJS, and Vuex, providing reactive and declarative approaches to UI updates.
Today, event-driven principles power real-time messaging apps, collaborative tools, and even IoT ecosystems where devices react dynamically to changes in their environment.
The CRUD Approach vs. Event-Driven Architecture
Many web applications follow a CRUD (Create, Read, Update, Delete) approach: you fetch a resource from the backend, allow the user to modify it, and send the updated resource back. This results in UI structures built around data operations—list views, create/update forms, and delete actions. For example, if you’re building a blog, a CRUD mindset means focusing on creating, updating, and deleting posts.
However, humans don’t think in terms of updating data. We use applications to accomplish tasks quickly. Wouldn’t it be more intuitive to model the application around tasks instead of data manipulations? For example, instead of manually updating post statuses, you could display a list of unpublished posts with a ‘Release’ button to quickly publish them.
Event-driven architecture (EDA) shifts this paradigm by modeling actions as discrete events. Instead of thinking in terms of direct data modifications, developers focus on capturing user intents and allowing the system to react accordingly.
Modeling Around Events
Starting with Commands
To simplify the shift in thinking, let’s introduce a small trick: separate UI interactions from UI state. Instead of directly modifying data, the UI should only dispatch commands—user intents that trigger backend logic. Consider this example of emitting an event to a global RxJS subject.
import { Subject } from 'rxjs';
const GlobalEvent$ = new Subject();
class ReleasePostEvent {
public readonly type = 'POST_RELEASE_COMMAND';
public readonly payload = new ReleasePostPayload();
}
class ReleasePostPayload {
public postId: string;
}
const UiComponent = ({ postId }) => {
const handleReleasePost = (postId: string) => {
const event = new ReleasePostEvent();
event.payload.postId = postId;
GlobalEvent$.next(event);
};
return <button onClick={() => handleReleasePost(postId)}>Release</button>;
};
This small shift changes how the application is structured. Instead of directly modifying the post’s status, the system captures the user's intent and acts upon it asynchronously.
By decoupling state changes from UI interactions, applications gain significant performance improvements, reducing re-renders and unnecessary network requests.
What Happens to These Events?
This is where the magic happens: you can handle events however you like. 🚀
Instead of tightly coupling state changes to UI actions, events allow for greater flexibility. Here are some possibilities:
- Update stored models on the server.
- Send events to analytics tools like PostHog.
- Log events to the browser console during development.
- Trigger workflows that notify other parts of the application.
Imagine a customer requests a feature: “When X happens, can you also do Y?” With an event-driven model, you’re already prepared to handle it efficiently without reworking the entire architecture.
Combining Events for Smarter UI State
Consider a loading indicator: in a CRUD-based system, you typically set a boolean
flag in the application state. With events, you don’t need explicit state management. If a ‘loading’ command is dispatched and a corresponding ‘resource loaded’ event hasn’t been received yet, you know the application is still loading. The logic could look like this:
import { filter, map } from 'rxjs';
const isLoading$ = GlobalEvent$.pipe(
filter(event => event.type === 'LOADING_COMMAND' || event.type === 'RESOURCE_LOADED'),
map(event => event.type === 'LOADING_COMMAND')
);
This pattern allows applications to remain more predictable and avoids unnecessary UI state management.
Conclusion
Moving beyond CRUD-based thinking and embracing event-driven architecture enables applications to be more responsive and adaptable. By focusing on what happens instead of how data is updated, you create a system where business logic is decoupled from UI interactions, making your frontend more powerful and resilient.
Adopting this mindset might require a shift in thinking, but the benefits—better scalability, maintainability, and responsiveness—make it a powerful approach for modern frontend development.
Top comments (2)
Welcome to the writer’s family, Jens-Uwe Lössl! 🖋️✨
Your voice matters, and we’re excited to have your perspective here. Keep sharing your ideas, and let’s make something great together! 🚀
I am a fan of event-driven architectures. However, RxJS and React are really not the way to get it right. Not even close. Coming from a framework author.