Step 1. Define rich, type‑safe domain model

Describe commands, events, and state of entities using Protobuf.

// A command to craete a new task.
message CreateTask {
    TaskId id = 1;
    string name = 2 [(required) = true];
    string description = 3;
}
...
// A new task has been created.
message TaskCreated {
    TaskId id = 1;
    string name = 2 [(required) = true];
    string description = 3;
}
...
// A state of the Task aggregate.
message Task {
    TaskId id = 1;
    string name = 2 [(required) = true];
    string description = 3;
    DeveloperId assignee = 4;
}

Step 2. Generate the code for all tiers and multiple languages

Java, JavaScript, and C++ are currently supported, with more languages to come soon.

Generate code

Step 3. Code business logic in straight and testable way

Focus on the business logic rather than “plumbing”. A Command will be delivered to only one Aggregate. Projections will get all Events they need. ProcessManagers will cover more complex scenarios. Storage, message delivery, and other environment matters are isolated from the main code.

final class TaskAggregate
    extends Aggregate<TaskId, Task, TaskVBuilder> {
    ...
    @Assign
    TaskCreated handle(CreateTask cmd, CommandContext ctx) {
        return TaskCreated
                .newBuilder()
                .setId(cmd.getId())
                .setName(cmd.getName())
                .setOwner(ctx.getActor())
                .build();
    }
    ...
}
final class TaskProjection
    extends Projection<TaskId, TaskItem, TaskItemVBuilder> {
    ...
    @Subscribe
    void on(TaskCreated e) {
        getBuilder().setId(e.getId())
                    .setName(e.getName())
    }

    @Subscribe
    void on(TaskCompleted e, EventContext ctx) {
        getBuilder().setWhenDone(ctx.getTimestamp());
    }
}

Step 4. Easily deploy to Google Cloud or a custom environment

In-memory and JDBC-based storage implementations allow to implement and test the core logic quickly. Adopt your application to selected deployment environment(s) with a few lines of code.

Evolve your domain model

Features

Type Safety

Should you need CustomerId or WorkEstimate value, you get it within seconds, for multiple languages. And it all comes with binary storage format, and automatic Json support.

Promoted immutability

All the data types are immutable, which makes it easy to cache and share. Mutations are performed only in response to incoming messages via clearly defined cycles.

Evolve your business model

Add and remove fields while keeping binary compatibility with older code; handle new opportunities with oneof, natively provided by Protobuf. Build new Projections on the whole event history of the system.

Develop faster, with better results

Thanks to CQRS and Event-Driven Architecture, you can arrange clear work separate. More experienced developers work on the core domain and the write-side. The read–side and UI are created by the rest of the team.

Scale with micro-services

CQRS architecture allows to scale read- and write- sides independently. When further scaling is needed, Event-Driven Architecture allows to further separate and scale heavily loaded parts.

Use freely

Permissive Apache License allows using the framework in closed-source projects. You are welcome to contribute to improving the framework.

Want to learn more?

Get started by learning concepts and exploring example applications.