We have legacy app which keeps state of a cart in local storage on a Frontend (this decision was made long time ago by other devs). The cart is cleared from local storage after 2 hours if it is not completed.
Now we are moving towards microservices, and one of new microservice is 'Discount Coupons'. Customer can apply coupon which will reduce final price he/she needs to pay. In order to have a discount, customer needs to apply a coupon (click 'apply'). There can be only 1 coupon applied per cart.
Customer can go back and forth the cart screen, and if coupon was applied it should appear as applied (keep in mind cart is legacy part, while Coupons is new microservice).
There are 2 contradiction approaches we struggle to agree on:
approach 1: keep information if Coupon is applied in Backend, in
Coupons table, in column
approach 2: keep which coupon (null if none) was applied in current Frontend implementation of a cart state.
Disadvantage of approach 1 is that the final state of a cart will be distributed in 2 places (FE local storage and BE
Coupons table). What is more, there is a risk of inconsistency, because in DB more than 1 customer's coupon can be in 'applied' state (unless we execute logic to prevent it on every change). Also we need to keep in sync FE local cart state with BE coupons state, which will make DiscountCoupons microservice stateful (while there is an opinion that stateless is preferable).
Disadvantage of approach 2 is that every time coupons are
DiscountCoupons API (about 10-20 items in single GET request) they need to be compared against local FE cart state to determine which of them (if any) is in applied state.
Here go my questions:
- Is 'distributed state' an anti-pattern or is it perfectly fine? I have read a lot about distributed transactions (e.g. to avoid them, and if not possible, to do saga pattern), but I'm struggle to find any articles about distributed state.
- Should a coupon know that it is applied, or should cart know that it has coupon applied on it?