System consists of several micro-services and each of them is in charge of it's own context, such as booking, payment, products and notifications.

Let's imagine we have a traveler who is seeking accommodation on website. Accommodation is listed by retrieving information from products micro-service. Traveler found what he wants and decided to make a reservation.

He selects date, number of nights, people etc, and submits a request to booking micro-service. Request contains all payment details and booking details. Here comes the fun part:

  1. Request creates a reservation record with status pending and publishes event, reservation_created.
  2. Payment service pools for that event, creates a credit card authorization and publishes event authorization_successfull with booking ID inside event payload.
  3. Product micro-service pools for authorization_successful event and checks if accommodation is really available for the requested period. If everything is ok, accommodation will be marked as occupied for desired period and publish availability_updated event.
  4. Booking micro-service will pool for that event and change reservation status to approved, which will then publish new event, so notifications micro-service can pool for it, and send necessary emails.

Now, I have several questions:

  1. This looks nice in theory, but am I over-complicating things, or this is a way to go to achieve decoupling?

  2. By going with this approach, I can't inform traveler "Reservation complete" since there is a long running process involved in the background. My guess is that info message should be more like "Reservation requested, you will receive confirmation email shortly, or i should pool one of service endpoints with loading screen, or even use web sockets to send notification back?"

  • Which of these services must be a (micro) service of its own? – Prasanna K Rao Sep 8 '16 at 12:10
  • @PrasannaKRao I've edited my question. Each service is on it's own. Booking, Products, Payments, Messaging – Robert Sep 8 '16 at 12:11

First thought: make the implicit explicit. The traveler is offering your an opportunity to derive business value; your absolute top priority at that point is to capture that opportunity -- everything else can wait. So you are missing a ReservationRequested event; choose whatever spelling is appropriate in the ubiquitous language of your domain.

This looks nice in theory, but am I over-complicating things, or this is a way to go to achieve decoupling?

It looks to me as though you are heading down the right road. You may want to review your design to see if Inventory (availability) is a separate concern from Product (marketing, pricing, etc).

By going with this approach, I can't inform traveler "Reservation complete" since there is a long running process involved in the background.

That's right - however, you should have enough information in the ReservationRequested event to know which long running background process will be associated with this Reservation (example: the process id is computed from a hash of values that are present in the reservation request).

My preference would be to ACK the request by redirecting the traveler to a view of the process in flight; if they follow the link before you make any progress, then you use the ReservationRequested event to build a representation of "We received your request, you can expect to hear from us by..." message, but that same endpoint can be used to provide updated representations of the process as work completes.

  • That's good to hear. I was under impression that I am publishing way too much events. – Robert Sep 8 '16 at 16:02

Your direction and design looks good, a couple of comments:

If you can get the UI or API to do the message distribution (instead of the Request service doing that), by having each business component do it's work and publish an event, this will introduce less coupling and better scale opportunities.

Another pattern you can use is Saga (state machine) so you can orchestrate the business process better and know when you are done by listening to all the events...

You can look at an example of a Saga implementation here

Make sense?

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.