Search code examples
node.jsarchitecturesubscription

How to access multiple remote services in transaction-like manner


I have an endpoint responsible for creating a paid subscription. However, in order to create subscription I need to access multiple different services in succession:

1) create subscription with a token provided by front-end (generated by a direct call from front-end app to payment system) (Call to the payment system)

2) get Billing information to save in database (Call to the payment system)

3) save some of billing info (f_name, l_name) and provided shipping info (Call to the database)

4) subscribe customer to the mailing list (Call to the email service provider)

Any of these steps can fail due to service being unavailable, problems with internet connection in the DC or any other number of problems that are not controllable by developers. Is there any options to process all of this in a transaction-like manner to avoid partial completion? e.g. We create subscription, but don't write to database.

I am using Node.js, if this helps.


Solution

  • Have a look at the Saga pattern for microservices. This could essentially be laid out as a service which you contact when you want to create a subscription. It knows every step involved and on top of that, also knows how to roll back every transaction, should any step fail.

    Upon making a request, the service would just start doing all the necessary requests/queries and then either:

    1. Return successfully
    2. Rollback all transactions that have happened so far and return an error

    This obviously relies on all of your services being able to revert to known good state.

    Another approach would be to use two-phase/n-phase commits, but they may impose a big performance drop which is not desirable for something user-facing.

    You may want to read through this discussion on HackerNews where this problem is discussed in far more detail.