395 karma · joined April 30, 2018
However, for various parts of my application that seem high-complexity, high-impact and non-competetive edge (such as authentication and credit card handling) I want to outsource to external services (Auth0 and Stripe). This brings with it the challenge of managing state, and consistency across various external services (on top of the state I manage internally).
The reason microservices is mentioned in the question, is because I believe these problems generalise from my specific case, to microservices.
I did find some pretty good resources on Sagas - do you have any thought on comparing Sagas pro/cons vis-a-vis this approach?
This outsourcing of high-impact, high-complexity does come with the disadvantage of now having to deal with external services. As far as I can tell, the atomicity/transactional problem with these external services generalises to microservices - hence the microservices tag.
The way I have tried to implement (very likely, shoddily) idempotency is to have each mutation on an external service (say creating a customer in Stripe, corresponding to an account already administered in my database) first check if a customer with that ID already exists, and if not to create it - otherwise use the existing object (Stripe customer in this example).
``` user = Database.get_user(my_user_id)
if (Stripe.customer_exists(user.id) { return Stripe.get customer(user.id) } else { stripe_customer = Stripe.create_customer(user.id, user.email) Database.set_user_property("stripe_customer_id", stripe_customer.id) return customer } ```
The problems here are multiple, but at the very least I see the possibility of very nasty bugs if somehow the `customer_exists` call returns a false negative - this will cause the same customer to be created in Stripe twice (and thus potentially be charged twice). Another, more likely, issue is that between the `Stripe.create_customer` call and the `set_user_property` there may be an unexpected event (service/network goes down, whatever) failing to store the property - leading to a duplicate Stripe customer the next time the above code is executed. On top of that, I find it pretty difficult to reason about a code base chock full of this type of logic (perhaps that is just my personal limitation though!).
Leaving you 'empty handed', or only paying you the share of the incorporation fee also sounds unreasonable - you did invest time and effort and that largely remains unvalued in that case.
In the past I have dealt with similar situations by agreeing on the amount of hours and effort spend, and attach a market value to that. The leaving party then is paid that amount (either in whole, or stretched out over a period) and no equity is retained.