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:
- Check if existing user already have a booking
- Get list of available drivers
- Send notification to the drivers to pick up the booking
- 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 notificationsBooking
– 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 🙂
Best Answer
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
andnotification
services. You don't need thedriver
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:
booking
service to get a list of available driversbooking
servicebooking
service service calls thenotification
service with the booking detailsnotification
service sends a notification to the driver, notifying him of the bookingnotification
service when they are within a mile of the customernotification
service sends the alert to the customer that their driver is almost thereHope 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.