Skip to content

victorrentea/spring-modulith

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Modular Monolith Exercise

using Spring Modulith https://spring.io/projects/spring-modulith/

API Overview

  • Catalog: Search product
  • Catalog: Get product details
  • Order: Place order, returning a redirect url to a payment page
  • Inventory: Add stock
  • Inventory: Get stock bulk
  • Inventory: Reserve stock (confirmed via OrderConfirmedEvent)
  • Customer: Get customer address

Spring Modulith Intro

A module can only reference by default the classes in the top-level package of other modules. A class in any subpackage (eg. impl) is considered implementation detail, and it should NOT be accessed from outside that module.

Modules cannot form dependency cycles.

A diagram overviewing the module interactions is auto-generated at each test run. See index.adoc

Exercises

Taking small baby-steps, implement the changes below. Expand the hints if needed, and keep running ArchitectureTest:

  1. Return the number of items currently in stock from GetProductApi
  • catalog should not access any internal class of inventory module (run tests).
  • GetProductReturnsStockE2ETest should pass.
  • HintRetrieve the stock item number via a call to a new method in `InventoryModule`
  1. Pull payment-related classes out of order module into a separate payment module.

    • Check there are no illegal internal calls or cycles with ArchitectureTest
    • Hint to fix 'non-exposed..':Code having to do with the `order` internals should stay in `order`.
    • Hint to fix cycle:Solution#1Have a `PaymentCompletedEvent` thrown from payment back into order
    • Hint to fix cycle:Solution#2Introduce an interface in one of the modules implemented in the other (aka Dependency Inversion). Which module should hold the interface?
    • Encapsulate the new payment module: hide as many classes exposing the least amount of public stuff
    • HintMove classes in a subpackage, like 'impl'
  2. SearchProductApi should only return products in stock

    • What options you see? Tradeoffs of each?
    1. OptionFind all products and join in-memory with all stock. Or vice-versa.
    2. OptionJOIN Stock via SQL/JPQL😐
    3. OptionReplicate stock item number at every change via events from `inventory`
    4. OptionPublish `OutOfStockEvent` and `BackInStockEvent` from `inventory`, updating a `Product.inStock` boolean;
    5. OptionJoin the Product with the StockView @Entity exposed by `inventory`
  3. Notifications

    • When payment is confirmed

    • Hint - code snippet
       public void onOrderStatusChanged(OrderStatusChangedEvent event) {
         String customerEmail = customerModule.getCustomer(event.customerId()).email();
         if (event.status() == OrderStatus.PAYMENT_APPROVED) {
           sendPaymentConfirmedEmail(event, customerEmail);
         }
         if (event.status() == OrderStatus.SHIPPING_IN_PROGRESS) {
           sendOrderShippedEmail(event, customerEmail);
         }
       }
      
  4. Move Reviews-related stuff out of catalog module

    • E2E Test should still pass

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages