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

Builiding Modular monoliths that can scale to m...

Builiding Modular monoliths that can scale to microservices. JBCNConf 2021

It’s easy these days to fall into the trap of starting to design your whole application with a microservices architecture…. Because, you know, that’s what everyone is doing. Aren't they?
But, are we considering the microservices architecture as a goal or as a means to a purpose?

In this talk, we will go back to the basics and see how DDD, CQRS and EventSourcing practices drive our application design and evolution so that we will start with a monolith. Still, we will have the ability to scale into microservices more or less easily when (and more importantly: if) we need to.

These are the slides I used in my talk at JBCNConf 2021

Avatar for David Gómez G.

David Gómez G.

July 23, 2021

Other Decks in Technology

Transcript

  1. David Gómez G. Developer Advocate . Building monolith applications that

    can scale to micro services (only if they need to) @AXONIQ @DGOMEZG
  2. Don’t let the microservices hype ruin your project @DGOMEZG @AXONIQ

    @DGOMEZG David Gómez G. Developer Advocate .
  3. Or you may need to add a new module/feature to

    an existing project @DGOMEZG
  4. @DGOMEZG What you need (Your steps) • Separate your different

    tasks by type • Focus on understanding the problem(s) you need to solve, • Model each problem independently • Be prepared to grow & scale (both in features and in performance) • Don’t couple to other components
  5. @DGOMEZG Our example A Conference Management Tool. Dates, Sponsors, Call

    For Papers, Proposals, Agenda T alks, Tickets, Attendees… Call For Papers, Agenda, Questions, Forums, Tickets, Agenda, speakers, …
  6. @DGOMEZG CQRS Separate Queries from Commands COMMANDS What actions do

    require changes in the state of the application? What other changes will be necessary to notify/propagate?
  7. @DGOMEZG CQRS Separate Queries from Commands COMMANDS De fi ne

    Edition (Dates) Accept/Reject Talk Proposal Open Ticket sales Open Call For Papers Add/Remove Track De fi ne Q&A Channel Submit Proposal Withdraw Proposal Con fi rm Proposal Join Q&A Channel Buy Ticket Add Talk To My Agenda Ask Questions in Q&A. Rate Talk
  8. @DGOMEZG CQRS Separate Queries from Commands QUERIES List Proposals Get

    Talk Popularity Get Talks Rating Get Questions Get Talk Feedback My Talk Info Conference Agenda My Agenda Q&A Messages
  9. @DGOMEZG COMMANDS QUERIES Focus on modelling within the boundaries of

    each element Command model Projections Keep only relevant information for the action in each model
  10. @DGOMEZG Projections Projections maintain the structure of information close to

    how it is needed by the client/user ListRooms ROOM, DESCRIPTION, NUM_OF_MEMBERS GetRoomMessages DATE, USER, MSG DATE, USER, MSG DATE, USER, MSG
  11. @DGOMEZG Aggregate A set of objects, relationship and invariants that

    are considered as one unit with regard to data changes. De fi ne the boundaries in which some invariants are kept. They are a model of part of the domain.
  12. Why Event-Sourcing? ProposalUpdated (id: 123, title) SpeakerAdded (id:123, jDoe) ProposalSubmitted

    ProposalAccepted ProposalWithdrawn ProposalDraftSen t (id: 123) id: 123. Author: John Doe Title: What’s new in Java 17 status: WIthdrawn What happened What we store
  13. Why Event-Sourcing? Business Reasons Technical reasons • Reliability of decisions

    • Auditing / compliance / transparency • Data mining, analytics: value for data • Historic data useful for new features • Guaranteed completeness of event stream • Single point of truth • Concurrency / con fl ict resolution • Facilitates debugging / forensic analysis • Replay into new read models (scalability with CQRS)
  14. Location Transparency A component should neither be aware of nor

    make any assumptions about the location of other components Even more… Should not even know which components it interacts with
  15. Location Transparency A component should neither be aware of nor

    make any assumptions about the location of other components Even more… Should not even know which components it interacts with
  16. Location Transparency A component should neither be aware of nor

    make any assumptions about the location of other components Even more… Should not even know which components it interacts with
  17. Location Transparency A component should neither be aware of nor

    make any assumptions about the location of other components Even more… Should not even know which components it interacts with
  18. Location Transparency A component should neither be aware of nor

    make any assumptions about the location of other components Even more… Should not even know which components it interacts with
  19. Command Model data class CreateRoomCommand( @TargetAggregateIdentifier val roomId: String, val

    name: String) data class JoinRoomCommand( @TargetAggregateIdentifier val roomId: String, val participant: String) data class PostMessageCommand( @TargetAggregateIdentifier val roomId: String, val participant: String, val message: String) data class LeaveRoomCommand( @TargetAggregateIdentifier val roomId: String, val participant: String)
  20. Event Model data class RoomCreatedEvent( val roomId: String, val name:

    String) data class ParticipantJoinedRoomEvent( val roomId: String, val participant: String) data class MessagePostedEvent( val roomId: String, val participant: String, val message: String) data class ParticipantLeftRoomEvent( val roomId: String, val participant: String)
  21. Aggregate @Aggregate public class ChatRoom { @AggregateIdentifier private String roomId;

    private Set<String> participants; public ChatRoom() { } }
  22. Aggregate: Handling a Command @Aggregate public class ChatRoom { @AggregateIdentifier

    private String roomId; private Set<String> participants; @CommandHandler public ChatRoom(CreateRoomCommand command) { apply(new RoomCreatedEvent(command.getRoomId(), command.getName())); } @CommandHandler public void handle(JoinRoomCommand command) { apply(new ParticipantJoinedRoomEvent(command.getRoomId(), command.getParticipant())); } }
  23. Aggregate: Handling a Command @Aggregate public class ChatRoom { @AggregateIdentifier

    private String roomId; private Set<String> participants; @CommandHandler public void handle(JoinRoomCommand command) { apply(new ParticipantJoinedRoomEvent(command.getRoomId(), command.getParticipant())); } @EventSourcingHandler public void on(ParticipantJoinedRoomEvent event) { this.participants.add(event.getParticipant()); } }
  24. Location Transparency. Sync other components @Component public class RoomSummaryProjection {

    private final RoomSummaryRepository roomSummaryRepository; @EventHandler public void on(RoomCreatedEvent event) { roomSummaryRepository.save(new RoomSummary(event.getRoomId(), event.getName())); } @EventHandler public void on(ParticipantJoinedRoomEvent event) { roomSummaryRepository.findById(event.getRoomId()) .ifPresent(RoomSummary : : addParticipant); } }
  25. Useful Resources https://lp.axoniq.io/jbcnconf The slides Code-sample & tutorial repo Free

    DDD, CQRS & ES courses eventmodeling.org Domain-Driven Design lp.axoniq.io/jbcnconf Axon OS tools Link to ask for your t-shirt