Let’s say we have a User, Wallet REST microservices and an API gateway that glues things together. When Bob registers on our website, our API gateway needs to create a user through the User microservice and a wallet through the Wallet microservice.
Now here are a few scenarios where things could go wrong:
-
User Bob creation fails: that’s OK, we just return an error message to the Bob. We’re using SQL transactions so no one ever saw Bob in the system. Everything’s good 🙂
-
User Bob is created but before our Wallet can be created, our API gateway hard crashes. We now have a User with no wallet (inconsistent data).
-
User Bob is created and as we are creating the Wallet, the HTTP connection drops. The wallet creation might have succeeded or it might have not.
What solutions are available to prevent this kind of data inconsistency from happening? Are there patterns that allow transactions to span multiple REST requests? I’ve read the Wikipedia page on Two-phase commit which seems to touch on this issue but I’m not sure how to apply it in practice. This Atomic Distributed Transactions: a RESTful design paper also seems interesting although I haven’t read it yet.
Alternatively, I know REST might just not be suited for this use case. Would perhaps the correct way to handle this situation to drop REST entirely and use a different communication protocol like a message queue system? Or should I enforce consistency in my application code (for example, by having a background job that detects inconsistencies and fixes them or by having a “state” attribute on my User model with “creating”, “created” values, etc.)?