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)
- Command Class: Defines an action to be performed. For instance,
CreateUserCommandwith fields likeuserId,name, andemail. - Command Handler: Processes the commands. It would take
CreateUserCommand, perform business logic, and persist the changes. - Domain Model: Represents the state of the data (e.g., a
Userclass). - Repository: Handles data persistence.
2. Query Model (Read Model)
- DTO (Data Transfer Object): Represents the data we want to read, like
UserProfileDTO. - Query Class: Defines a query, for instance,
GetUserProfileQuerywith auserId. - Query Handler: Handles the query and returns the requested data, often using a read-optimized storage.
3. Infrastructure
- Command Bus: Routes commands to their respective handlers.
- Query Bus: Routes queries to their respective handlers.
- 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
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.
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.
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.
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.
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.