3factor: the architecture that removes state from the API
In early 2019, a few months after discovering the twelve factors, I come across 3factor , an architecture pattern published by Hasura whose name is an assumed wink at 12factor.net (the resemblance ends there, 3factor is a design pattern, not a methodology). The idea fits in three factors: realtime GraphQL, reliable eventing and async serverless.
The three factors
The first factor is realtime GraphQL: the client subscribes to the state and receives it instead of asking for it, which moves the synchronisation from polling to the server. The second is reliable eventing: every state change is a persisted event. Triggers triggers deliver it to subscribers (delivery happens at least once, idempotency is the consumer’s job). The third is async serverless: the business logic runs in functions triggered by events, with no server to manage and automatic scaling.
The central idea
The pattern fits in one movement: state, event, reaction. State lives in the database, the event moves it out, the reaction moves it forward. State management leaves the API layer, which becomes a mere projectionist (it projects the state and subscribes to it). The business logic lives in the reactions. It is the opposite of a REST API that carries the session, the computation and the consistency.
What it costs
The pattern is not free. You must accept eventual consistency, since state and events are not transactional together. You must think idempotency, since events are delivered at least once. And you must give up complex one-shot queries, since the state is rebuilt by subscription. In exchange, you gain a stateless API (which the twelve factors recommend) and a business logic that scales independently.
The link with the twelve factors
On the Twelve-Factor side, the pattern ticks several boxes: stateless processes, dev/prod parity, logs as streams. It pushes the concurrency factor farthest of all, since each reaction is an independent process. I file it in the same family as the twelve factors, younger and more stubborn.