Before OOP languages, the programmer would control how the program is executed and that would be from the app’s main routine. In modern programming, that control is delegated to the external non-main loops, and the main routine becomes an event-loop that waits for events to occur and then executes it with the relevant event handler.
This new model of programming (it has been around since the 70s though) is called event-driven programming.
What Is Event-Driven Programming?
In event-driven programming, user actions and interactions are the triggers that initiate the next flow of events. Apps built in 2021 are generally made with the user at the center of the programmer’s thinking, and as such, are created to respond to any sort of user commands.
In this asynchronous programming model, as mentioned above, there’s usually an event-loop that looks out for new events as they come in. Once an event is initiated, an event handler is triggered at the specific time that the event is produced.
These procedures that are triggered can be either stored routines or external programs. Thus, the control of the flow of the program execution is external, largely invisible to the programmer, and there’s no discernible flow of control.
What Are 3factor Apps?
3factor app is a modern artificial pattern for building modern full-stack applications. The 3factor architecture pattern is fully aligned with the event-driven programming paradigm, and uses the following 3 “factors”:
- Realtime GraphQL.
- Reliable Eventing.
- Asynchronous (Async) Serverless.
Here’s an example of a food ordering application that’s built in the traditional model vs the 3factor methodology:
The core of the whole model is that all the business logic is triggered by events.
1. Realtime GraphQL
The GraphQL layer allows flexible API access and is used for mutating and manipulating states while receiving real-time updates to state changes. This GraphQL layer should be:
- Low-latency: The user should be able to get instant feedback from the application for any action.
- Support subscriptions: Avoid continuous polling by being able to consume real-time information from the backend through GraphQL subscriptions.
The traditional model used REST APIs to interact with the backend, fetched related data via multiple calls, used tools like Swagger for API docs, required the setup of custom APIs for real-time (or polling). Meanwhile, 3factor uses GraphQL APIs for backend interaction, can fetch any kind of data in a single cell, auto-generate the entire API schema and related docs, and use native GraphQL subscriptions to consume info in real-time.
2. Reliable Eventing
From the example diagram discussed above, we can see that the business logic is invoked by events, thus leaving your API layer free from complex state management which can be delegated to specifically created business logic programs or functions.
It is recommended that the events be persisted for the sake of observability of the entire state change history. And the event system should also be:
- Atomic: Any mutations to the state of the application should atomically create an event(s).
- Reliable: Events should be delivered with an at-least-once guarantee.
In the 3factor model, on an API call, we can produce and persist event(s) that represent the action and the eventing is fundamentally asynchronous. But, the seamless error recovery handling is arguably the most beneficial advantage to making the application event-driven. In a traditional workflow, there needs to be some additional error recovery logic that has to be implemented in case of a crash, but there’s no need for such logic since the app is emitting atomic events that can be easily retried in the case of a crash.
3. Async Serverless
Since the main routine is just an event-loop made up of event handlers, the complex business logic can be in the event handling functions themselves where each function is small and cohesive and deals only with one event. These functions can be deployed using serverless backends and that will result in minimizing backend ops and is highly cost-effective when scaling.
These serverless functions imbibed with complex business logic should be:
- Idempotent: Should be prepared for duplicate delivery of events.
- Out of order: Sharks are known to eat the undersea copper wiring that powers a lot of the internet. That and more realistic issues may cause the events to be received out of order and hence the code should be able to process this without depending on an expected sequence of events.
The 3factor model allows us to write loosely coupled event handlers, lets us deploy on serverless platforms, doesn’t require us to manage the runtime (the platform does it), doesn’t require operational expertise, and is inherently auto-scaling.
The event-driven programming paradigm coupled with the 3factor app architecture pattern is the most modern way of building apps in 2021. There are arguments against event-driven programming such as only GUI apps will benefit and others don’t need it or it’s too complex for simple apps, but along with the 3factor methodology, it’s a powerful tool focused on speed, reliability, scalability and has the user in focus.