Start Building
Responsive|
Distributed
Systems
Evento is the Java framework
to build RECQ architectures —
where the architecture is enforced, not hoped for.
Develop RECQ
Components in Java
- Easy implementation of Invokers, Services, Aggregates, Projectors, Projections, Sagas and Observers in Java.
- Use annotations to define the component type and Command, Query or Event handlers.
- Implement interactions with the Message Gateway.
- Evento Framework works great even with other Java frameworks like Spring, Micronaut, Quarkus.
Hover the annotations to flip through real code from the live demo →
@Invoker
public class TodoListInvoker extends InvokerWrapper {
@InvocationHandler
public String createTodoList(String name, String user) throws Exception {
var identifier = "TDLS_" + UUID.randomUUID();
getCommandGateway()
.send(new TodoListCreateCommand(identifier, name),
toUserMetadata(user))
.get(30, TimeUnit.SECONDS);
return identifier;
}
@InvocationHandler
public CompletableFuture<TodoListView> findTodoListByIdentifier(String id) {
return getQueryGateway()
.query(new TodoListViewFindByIdentifierQuery(id))
.thenApply(Single::getData);
}
}
@Saga(version = 1)
public class ErpTodoListActivityRegistrationSaga {
@SagaEventHandler(init = true, associationProperty = "identifier")
public SagaState on(TodoListCreatedEvent event) { /* start tracking */ }
@SagaEventHandler(associationProperty = "identifier")
public void on(TodoListTodoCheckedEvent event, SagaState state,
CommandGateway commandGateway) throws Exception {
if (event.isAllChecked()) {
commandGateway.send(new ErpUserActivityRegisterCommand(
"TodoList", event.getIdentifier(), state.getUsages()
)).get();
}
}
}
@Projection
public class TodoListProjection {
@QueryHandler
public Single<TodoListView> handle(TodoListViewFindByIdentifierQuery q) {
return Single.of(repository.findById(q.getIdentifier())
.map(TodoList::toView).orElseThrow());
}
@QueryHandler
public Multiple<TodoListListItemView> handle(TodoListListItemViewSearchQuery q) {
return Multiple.of(repository.search("%" + q.getNameLike() + "%",
PageRequest.of(q.getPage(), q.getSize()))
.map(TodoList::toListItemView).toList());
}
}
@Projector(version = 2)
public class TodoListProjector {
@EventHandler
public void on(TodoListTodoCheckedEvent event, Metadata metadata,
Instant timestamp, ProjectorStatus status) {
var list = repository.findById(event.getIdentifier()).orElseThrow();
var todo = list.todo(event.getTodoIdentifier());
todo.setCompletedAt(timestamp.atZone(ZoneId.systemDefault()));
todo.setCompletedBy(metadata.get("user"));
repository.save(list);
if (status.isHeadReached()) sse.notifyListChanged(list.getId());
}
}
@Aggregate
public class TodoListAggregate {
@AggregateCommandHandler
public TodoListTodoAddedEvent handle(TodoListAddTodoCommand command,
TodoListAggregateState state) {
Assert.isTrue(state.getTodos().size() < 5,
"Error: Todo list is full");
return new TodoListTodoAddedEvent(command.getIdentifier(),
command.getTodoIdentifier(), command.getContent());
}
@EventSourcingHandler
public void on(TodoListTodoAddedEvent event,
TodoListAggregateState state) {
state.getTodos().put(event.getTodoIdentifier(), false);
}
}
Evento GUI · Catalog
Navigate the Catalog
The rigorous semantic of the RECQ Pattern lets Evento Server generate the System Catalog automatically from your code — explore and visualize the interactions of every Payload, Component and Bundle.
// Your javadoc, your annotations, your handlers…
/**
* Manager of the user's todo lists:
* validates commands, emits events.
*/
@Aggregate
public class TodoListAggregate { … }
scanned at startup — zero extra work
📖 TodoListAggregate Aggregate
Manager of the user's todo lists: validates commands, emits events.
↗ view source on GitHub
Evento GUI · Documentation
Documentation that can't lie
- Evento Server scans your bundles at startup — payloads, components and handlers become the catalog. No wiki, no stale diagrams.
- Rename a command, add a handler — the docs update themselves with the next deploy.
- Every handler deep-links to its source line on GitHub.
Evento GUI · Flows & Application Graph
Understand your RECQ Architecture
Flows render every interaction as a tree — how components cooperate, where to optimize. Explore your entire system or a subset, starting from a Payload, a Component or a Bundle, then switch to the Application-Graph to interact with the whole architecture at once.
Evento GUI · Performance
What-If Performance Analysis
Given a workload, estimate the concurrent requests handled by each handler, component and bundle — the algorithm detects the bottleneck of every interaction. Tune workload, service time and invocation frequency to find the best optimization or estimate computational resources before you buy them.
New
Evento 2 is here
The second generation of the framework rebuilds the entire transport and consumer runtime — same seven components, industrial-grade internals.
Binary CBOR protocol
A new Netty transport with length-prefixed CBOR frames, transparent chunking (no message-size limit) and optional TLS.
Exactly-once QoS
Broker and bundle dedupe caches with response replay across reconnects — commands and events arrive once, in order.
Self-registering bundles
No JAR uploads, no deploy scripts: bundles announce themselves over the bus and appear in the catalog instantly.
Java 25 + virtual threads
Built for modern Java: virtual-thread executors end-to-end and Spring Boot 3.5 LTS compatibility.
Pluggable consumer stores
Projector, saga and observer state on Postgres or MySQL via focused SPIs — auto-migrated at startup.
Source-linked GUI
Every handler in the GUI deep-links to its exact source line on GitHub. The catalog is the codebase.
Born from research, proven in production
7
component types — formally minimal, proven irredundant
235 kLOC
production manufacturing-execution system running on RECQ — 206 components, censused
2023
first peer-reviewed publication (QualITA’23) and founding master’s thesis
Do you find Evento Framework and RECQ Architectures interesting?
Evento Framework is FREE and Open Source. You can always support the project by giving a star on GitHub or contributing to the code base.
