Knowledge Guide
HomeSystem DesignMicroservices Patterns

CQRS Pattern An Example

Let's consider a simple application that manages user profiles. In this application, you can create a new user (command), update their email (command), and view user details (query).

1. Command Model (Write Model)

  1. Command Class: Defines an action to be performed. For instance, CreateUserCommand with fields like userId, name, and email.
  2. Command Handler: Processes the commands. It would take CreateUserCommand, perform business logic, and persist the changes.
  3. Domain Model: Represents the state of the data (e.g., a User class).
  4. Repository: Handles data persistence.

2. Query Model (Read Model)

  1. DTO (Data Transfer Object): Represents the data we want to read, like UserProfileDTO.
  2. Query Class: Defines a query, for instance, GetUserProfileQuery with a userId.
  3. Query Handler: Handles the query and returns the requested data, often using a read-optimized storage.

3. Infrastructure

  1. Command Bus: Routes commands to their respective handlers.
  2. Query Bus: Routes queries to their respective handlers.
  3. Event Store: In a more advanced CQRS setup, this would store events resulting from commands.

Here is the sample code for the aforementioned components:

Command Model (Write Model)

1. Command Class

public class CreateUserCommand { private String userId; private String name; private String email; // Constructor, Getters, and Setters } public class UpdateUserEmailCommand { private String userId; private String newEmail; // Constructor, Getters, and Setters }

2. Command Handler

public class CreateUserCommandHandler { private UserRepository userRepository; public CreateUserCommandHandler(UserRepository userRepository) { this.userRepository = userRepository; } public void handle(CreateUserCommand command) { User user = new User(command.getUserId(), command.getName(), command.getEmail()); userRepository.save(user); } } public class UpdateUserEmailCommandHandler { private UserRepository userRepository; public UpdateUserEmailCommandHandler(UserRepository userRepository) { this.userRepository = userRepository; } public void handle(UpdateUserEmailCommand command) { if (!isValidEmail(command.getNewEmail())) { throw new IllegalArgumentException("Invalid email format"); } User user = userRepository.findById(command.getUserId()); if (user != null) { user.setEmail(command.getNewEmail()); userRepository.save(user); } } private boolean isValidEmail(String email) { // Simple email validation logic return email != null && email.contains("@"); } }

3. Domain Model

public class User { private String id; private String name; private String email; // Constructor, Getters, and Setters }

4. Repository

public interface UserRepository { void save(User user); User findById(String id); } public class UserRepositoryImpl implements UserRepository { // Implementation of save and findById methods }

Query Model (Read Model)

1. DTO (Data Transfer Object)

public class UserProfileDTO { private String id; private String name; private String email; // Constructor, Getters, and Setters }

2. Query Class

public class GetUserProfileQuery { private String userId; // Constructor, Getters, and Setters } // Read Email Query public class ReadUserEmailQuery { private String userId; // Constructor, Getters, and Setters }

3. Query Handler

public class GetUserProfileQueryHandler { private UserRepository userRepository; public GetUserProfileQueryHandler(UserRepository userRepository) { this.userRepository = userRepository; } public UserProfileDTO handle(GetUserProfileQuery query) { User user = userRepository.findById(query.getUserId()); return new UserProfileDTO(user.getId(), user.getName(), user.getEmail()); } } // Read Email Query Handler public class ReadUserEmailQueryHandler { private UserRepository userRepository; public ReadUserEmailQueryHandler(UserRepository userRepository) { this.userRepository = userRepository; } public String handle(ReadUserEmailQuery query) { User user = userRepository.findById(query.getUserId()); return user != null ? user.getEmail() : null; } }

Infrastructure

1. Command Bus

public interface CommandBus { void dispatch(CreateUserCommand command); } public class SimpleCommandBus implements CommandBus { private CreateUserCommandHandler handler; public SimpleCommandBus(CreateUserCommandHandler handler) { this.handler = handler; } @Override public void dispatch(CreateUserCommand command) { handler.handle(command); } }

2. Query Bus

public interface QueryBus { UserProfileDTO dispatch(GetUserProfileQuery query); } public class SimpleQueryBus implements QueryBus { private GetUserProfileQueryHandler handler; public SimpleQueryBus(GetUserProfileQueryHandler handler) { this.handler = handler; } @Override public UserProfileDTO dispatch(GetUserProfileQuery query) { return handler.handle(query); } }

3. Event Store (Simplified Example)

public interface EventStore { void storeEvent(UserEvent event); } public class SimpleEventStore implements EventStore { private List<UserEvent> events = new ArrayList<>(); @Override public void storeEvent(UserEvent event) { events.add(event); } }

Putting It All Together

java
public class CQRSApplication {
    public static void main(String[] args) {
        UserRepository userRepository = new UserRepositoryImpl();
        CreateUserCommandHandler createHandler = new CreateUserCommandHandler(userRepository);
        UpdateUserEmailCommandHandler updateEmailHandler = new UpdateUserEmailCommandHandler(userRepository);
        GetUserProfileQueryHandler queryHandler = new GetUserProfileQueryHandler(userRepository);
        ReadUserEmailQueryHandler readEmailHandler = new ReadUserEmailQueryHandler(userRepository);

        CommandBus commandBus = new SimpleCommandBus(createHandler, updateEmailHandler);
        QueryBus queryBus = new SimpleQueryBus(queryHandler, readEmailHandler);

        // Create User
        CreateUserCommand createCommand = new CreateUserCommand("1", "Alice", "alice@example.com");
        commandBus.dispatch(createCommand);

        // Update Email
        UpdateUserEmailCommand updateEmailCommand = new UpdateUserEmailCommand("1", "alice_new@example.com");
        commandBus.dispatch(updateEmailCommand);

        // Read Updated Email
        ReadUserEmailQuery readEmailQuery = new ReadUserEmailQuery("1");
        String updatedEmail = queryBus.dispatch(readEmailQuery);
        System.out.println("Updated Email: " + updatedEmail);

        // Read User Profile
        GetUserProfileQuery profileQuery = new GetUserProfileQuery("1");
        UserProfileDTO userProfile = queryBus.dispatch(profileQuery);
        System.out.println(userProfile);
    }
}

This example includes a basic implementation of a command bus, query bus, and a simplified event store. In a full-fledged application, an event store would be used for event sourcing, which is often paired with CQRS. The event store captures changes as a series of events, which can be replayed to rebuild the state of an entity.

🤖 Don't fully get this? Learn it with Claude

Stuck on CQRS Pattern An Example? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **CQRS Pattern An Example** (System Design) and want to truly understand it. Explain CQRS Pattern An Example from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **CQRS Pattern An Example** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **CQRS Pattern An Example** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **CQRS Pattern An Example** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes