Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CQRS in the small - with Modern Java and jOOQ

CQRS in the small - with Modern Java and jOOQ

Command Query Responsibility Segregation (CQRS) is a proven design pattern that enables the clear separation of data changes (commands) and data queries (queries). This separation allows each of these responsibilities to be scaled and optimized independently. An essential question in the application of CQRS is whether two separate data stores are necessarily required or whether CQRS can also be used effectively to keep data in a single database while still structuring the application code more efficiently and optimizing the data access.

In this talk, we will deepen the understanding of the practical implementation of the CQRS principles. We use jOOQ, a type-safe SQL query library, as our persistence layer and model both the query and command models using Java Records. Using a concrete example application, we demonstrate how the theoretical foundations of CQRS can be applied in practice and how this affects the design of applications and improves the data access performance.

Simon Martinelli

March 21, 2024
Tweet

More Decks by Simon Martinelli

Other Decks in Programming

Transcript

  1. CQRS in the small With Modern Java and jOOQ Simon

    Martinelli @simas_ch martinelli.ch
  2. Issue 1: Too Much • Over fetching • Loading data

    that is not needed • Not all data can be changed • Too much data is sent in the update request • Potential bugs if blindly mapped
  3. Issue 2: Too Little • Under fetching • Results in

    multiple requests • Produces the N+1 select problem on the client-side • Under storing • Updates/inserts not within the same transaction
  4. Modern Java: Records • Provide a compact syntax for declaring

    classes as transparent holders for immutable data Preview: 14 Final: 16 record AddItemCommand(long orderId, long productId, int quantity) {}
  5. Modern Java: Sealed Classes • Sealed classes and interfaces restrict

    which other classes or interfaces may extend or implement them Preview: 15 Final: 17 abstract sealed class Shape permits Circle, Rectangle, Square { }
  6. Modern Java: Switch Expression • Exhaustive: the switch expression must

    cover all cases • Preview in Java 12 and finalized in Java 14 String result = switch (color) { case RED -> "Red"; case GREEN -> "Green"; case BLUE -> "Blue"; }; Preview: 12 Final: 14
  7. Modern Java: Pattern Matching • instanceof operator • switch expression

    and statement double area = switch (shape) { case Circle c -> Math.PI * c.radius * c.radius; case Rectangle r -> r.length * r.width; default -> throw new IllegalArgumentException(); }; Preview: 14/17 Final: 17/21
  8. Modern Java: Record Patterns • Use to test whether a

    value is an instance of a record class type and, if it is, recursively perform pattern matching on its component values record Pair(int left, int right) {} if (p instanceof Pair(int left, int right)) { ... } Preview: 20 Final: 21
  9. Why jOOQ? Commands • Usually, insert, update, or delete data

    in the database • Use jOOQ to generate minimal updates Queries • Often return nested structures like Order à Item • jOOQ provides the MULTISET value constructor
  10. Conclusion • The separation of commands and queries improves the

    understandability • Avoids over- and under-fetching • Can make mapping Entity<->DTO obsolete • Enables an event-driven approach