using Spring Modulith https://spring.io/projects/spring-modulith/
- Search product (REST)
- Get product details (REST)
- Place order (REST): returns a redirect url to a payment page
- calls shipping provider with customer.address to get a shipping number
- Calls Payment Gateway to get payment redirect URL
- Is called back by Payment Gateway to report result
- Add stock (REST)
- API get stock bulk [pid,pid...]
- API reserve stock (orderid, items:[{},{},{}])
- publish OutOfStockEvent/BackInStockEvent
- listen OrderConfirmedEvent(orderid) to effect the stock reservation
- API get customer address (needed at shipping)
A module can only reference by default the top-level package of other modules. Any class in a subpackage (eg. impl
) is considered implementation detail and it's unaccessible from outside that module.
Modules cannot form cycles.
A diagram overviewing the module interactions is generated at each test run. See index.adoc
Taking small baby-steps, try to implement the following changes in code:
- Pull payment logic out of
order
module into a separatepayment
module.- Check there are no illegal internal calls or cycles with
ArchitectureTest
-
Hint
Have an event thrown from payment back into order -
Hint2
That event can be named PaymentCompletedEvent and should be placed in the payment module - Encapsulate the new 'payment' module: hide its internals exposing the least amount of public stuff
-
Hint
Use an 'impl' package for simplicity
- Check there are no illegal internal calls or cycles with
- Return the number of items in stock in product page (see
GetProductApi
)- Respect the encapsulation of
inventory
module (ArchitectureTest
should pass) -
Hint
Retrieve the stock item number via a call to a new method in `InventoryModule`
- Respect the encapsulation of
- Search should only return products in stock (see
SearchProductApi
)- What options can you identify. Tradeoffs of each?
-
Option
Find all products and join in-memory with all stock. Or vice-versa. -
Option
Force a JOIN via SQL/JPQL -
Option
Replicate stock item number at every change via events from `inventory` -
Option
Publish `OutOfStockEvent` and `BackInStockEvent` from `inventory`, keep a `Product.inStock` boolean; -
Option
A separate ElasticSearch engine to which you publish product{id,name} and stock{items} (just imagine)
- 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); } }
-