I'm developing a microservices based application and having trouble to understand how api calls should be organized between microservices ...
Suppose my application is a products management application.
As i understood each microservice should use it's own database , i'm going with this pattern.
Microservice Category -> db_categories
Microservice Product -> db_products
Microservice User -> db_users
Product microservice has user_id
as FK to users and category_id
as FK to categories.
Each user can post products
and products belong to category
.
--
Is this the correct way to implement a microservice based application?
If so , does it mean that if i want to populate each product with user object , i should make an api call to users
microservice for each user
or should i make an api call to users
microservice with a bulk of ids ?
The same applies for category?
As i know an API Gateway should be used , that will do user object and category object fetching. Also it will receive events.
There will be another microservices such as billing , payments , etc..
1 Answer 1
As identigral has mentioned in the comments, "There's no One True Way to implement microservices".
I'm pretty new to the microservices architecture myself but here's some advice I can offer.
Avoid synchronous service-to-service calls when possible
One of the biggest benefits of the microservice architecture is that your application is composed of several small-ish loosely coupled services. This is a benefit because it makes maintenance easier. You can work on a microservice in relative isolation knowing that it is very unlikely you'll affect the larger ecosystem (as long as you don't change that microservice's public contract).
When you make direct service-to-service calls you tighten the coupling between those services and loose this benefit.
Know which services own which entities
You mentioned populating Product
s with User
data when Product
and User
are actually owned by two different microservices.
Rather than duplicating the User
information in two services, it might make more sense for the Product
service to only store the subset of User
information it needs for its own purposes.
For this to work, the Product
service needs to understand that the User
service is the owner of that User
data. This means that changes to the User
information should always come from the User
service. The Product
service, if it is interested in those changes, should subscribe to events from the User
service and update its local copies as needed. I believe this approach is called "Eventually Consistent" and is a decent compromise to avoid forcing two microservices to be coupled by synchronous API calls and to avoid sharing ownership of data.
Be careful about your service boundaries
I think this is arguably the most difficult aspect of microservices. If your microservices are too large they can become mini-monoliths that are responsible for too many things and become difficult to maintain over time.
Conversely, if your microservices are too small, they just become thin views over data and defining behaviour over that data ends up being distributed awkwardly over multiple services.
Looking at your examples, I worry that you've gone down the route of making your services too small.
What I've found helpful in dealing with this is Domain Driven Design's concept of Bounded Context. In DDD, when modelling your application and its domain, you're encouraged to draw a map of all the main concepts and try to identify relatively isolated regions of data and behaviour. These relatively isolated regions are Bounded Contexts (BC) and tend to map really well to microservices.
Additionally, DDD talks about how multiple BC can have different versions of the same concept (eg, User
) without actually being duplicated data.
I'm still learning DDD but it's been a very helpful tool in navigating my first attempt at the microservice architecture. I'd recommend reading up on it.
-
That means , if a users posts 10000 products , i'll have to update each subset of user within product ?Dorin Musteața– Dorin Musteața04/04/2019 17:20:08Commented Apr 4, 2019 at 17:20
-
I don't know what your models look like, but that doesn't sound right. At worst, the product service would keep a copy of the user information it needs once. Not in every product record.MetaFight– MetaFight04/08/2019 10:01:24Commented Apr 8, 2019 at 10:01
-
Hi , I mean if a user posts 1 product , how would the product service get user details before returning a response to the client if the user details are not present in product service ? how do i save the details without attaching the details in a post request ?Dorin Musteața– Dorin Musteața08/01/2019 20:41:04Commented Aug 1, 2019 at 20:41
This question is more about "make sure" that this is the right way , based on what I understood or seeking for more advanced users to give a suggestion.
Other people's experience is helpful when they can resolve specific doubts about specific dead ends. However, the here question boils down to "What's the right way to handle IPC in MS architectures"?You can't invest time effectively if you are not sure what you are reading
. The only way to be sure you got something correct is through trial and error. Otherwise, you are just echoing other's opinions. That won't help you.