6

Still trying to wrap my head around microservice architecture since I'm used to a monolithic approach

Suppose we try to build a extremely simplified Uber booking system. To simplify things we let's say we have 3 services and a gateway api for the client: Booking, Drivers, Notification and we have the following workflow:

When creating new booking:

  1. Check if existing user already have a booking
  2. Get list of available drivers
  3. Send notification to the drivers to pick up the booking
  4. Driver picks up the booking

Let's say all messaging is done through an http call rather than a messaging bus like kafka to keep things simple.

So in this case, I thought that the Booking service can do the checking for existing booking. But then who should be getting the list of available drivers and notification? I'm thinking of doing it on the gateway level but then now logic is kind of split into two places:

  • Gateway - get list of available drivers + send notifications
  • Booking - check for existing booking

And I'm pretty sure gateway is not the right place to do it but I feel like if we are doing it in the Booking service, it's becoming tightly coupled?

To make it more complicated, what happens if we have another project that wants to reuse the booking system but with its own business logic on top of it? That's why I thought of doing it in the gateway level so the new project gateway can have its own business logic separate from the existing one.

Another way of doing it I suppose is to each project have its own booking service that will talk to the core booking service but I'm not sure what's the best approach here :-)

  • 2
    It's really hard to answer without the whole context. And even knowing this, start a project spreading the business logic on micro services is not always a good idea and this is why some people adopt the "Monolith First", because on the beginning you don't really know the responsibilities of each part of your application. This becomes clear only later. – Dherik Jan 11 at 11:31
4

People often hear "micro-service" and think "nano-service", and this can cause some confusion. These are micro-services, so you don't need a separate service for every single entity. Everything you are trying to do should be in the booking and notification services. You don't need the driver service (for any of the activity you described).

Getting a list of drivers available to book falls under the booking service. A common pitfall is to not group related activities into the same service, this is called low-coherence, and it is very bad. Remember, you group things into a service by problem domain, not by entity.

Now, as for reuse, the advantage of having a separate micro-service is, now you can have three separate teams making the consumer facing apps. One team for the standard html web app, an android app, and an ios app. All these different applications can be built completely differently, and look appropriate for their particular platform (without repeating code). The booking service code is reused by all three of these apps, because all three apps make http calls to the service instead having their own booking code.

A typical booking flow would look like this:

  1. The android app calls the booking service to get a list of available drivers
  2. The booking service returns a list of drivers to the app
  3. The user then selects their driver and the app calls the "book" method of the booking service
  4. The booking service service calls the notification service with the booking details
  5. The notification service sends a notification to the driver, notifying him of the booking
  6. The driver app sends a message to the notification service when they are within a mile of the customer
  7. The notification service sends the alert to the customer that their driver is almost there

Hope this helped; remember, they are micro-services, not nano-services, don't try to divide the same problem domain. So, to answer the title of your question, when you keep a micro-service the proper size, all, or most of, the business logic for that problem domain can live within that micro-service.

1

It all depends of your exact requirement.

Let's say you have two applications doing the booking :

  1. First case : One application may allow one users to book multiple times, the other allow only ones. This means that the restriction of the booking is on the application level, as such either you have two entry points in your booking system (one that allow multi booking, one that doesn't) or you just check that in the microservices of the relevant application.
  2. Second case : it is part of the definition of a "Booking" that a user can't have multiple ones whatever the application is, this rule is true for the whole system : this means you can put the check in the booking microservice.

As for the notifications system, you can have microservices suscribing to your booking service to listen for any new booking. As such the booking microservice will notify all subscribers and they will act accordingly.

The only problem in this kind of architecture is what happens if something fails after the notification has been published, since the two microservices don't work like two function executing in the same database transaction you will need to handle errors gracefully and eventually replay the processes that have failed (automatically or manually)

0

The simple answer is that clients of microservices are what manage the business logic in a 'pure' microservices architecture. To make it easier to understand, consider an even simpler example. A service that just returns streams of bytes based on a URI. By itself, it's not terribly useful. Without some way know which URIs have what in them, you can only guess at where to pull things. Now suppose you have a different microservice that provides a search capability. You send a request with a query string and it returns URIs. Now things get more interesting. I can put references to URIs for the first service into an index.

But still, we need to somehow coordinate between these two. There's a simple answer: you use a browser to retrieve URIs from the index service and then retrieve the data from the data service. Neither service 'knows' about the other and there's absolutely no coupling between them. I can use the index service with any other data service and vice-versa.

It's not necessarily the case that this is the best approach in all scenarios but there are many benefits to building things this way especially reusability in scenarios that are not currently known.

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.