using Spring Modulith https://spring.io/projects/spring-modulith/
- 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
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
Taking small baby-steps, implement the changes below.
Expand the hints if needed, and keep running ArchitectureTest
:
- Return the number of items currently in stock from
GetProductApi
catalog
should not access any internal class ofinventory
module (run tests).GetProductReturnsStockE2ETest
should pass.-
Hint
Retrieve the stock item number via a call to a new method in `InventoryModule`
-
Pull payment-related classes out of
order
module into a separatepayment
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#1
Have a `PaymentCompletedEvent` thrown from payment back into order -
Hint to fix cycle:Solution#2
Introduce 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 -
Hint
Move classes in a subpackage, like 'impl'
- Check there are no illegal internal calls or cycles with
-
SearchProductApi
should only return products in stock- What options you see? Tradeoffs of each?
-
Option
Find all products and join in-memory with all stock. Or vice-versa. -
Option
JOIN Stock via SQL/JPQL😐 -
Option
Replicate stock item number at every change via events from `inventory` -
Option
Publish `OutOfStockEvent` and `BackInStockEvent` from `inventory`, updating a `Product.inStock` boolean; -
Option
Join the Product with the StockView @Entity exposed by `inventory`
-
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); } }
-
-
Move Reviews-related stuff out of
catalog
module- E2E Test should still pass