0

I am creating a distributed chat system with a microservice architecture where a user can log in and chat with another user. The services that I identified is a conversation service that handles chat-related logic. Message service which handles and saves the messages and a user service that just has a simple authentication logic that is used to identify the users when logging in. Each of these services has its own database.

The problem that I came across is the Many-To-Many and Many-To-One relationships between these services. The issue is that the services need to know about each other to save and perform some specific actions. For example, the conversation service which handles the conversation/chat between two users needs to have messages saved for each conversation. This makes the conversation service in need to know about the message service which saves and retrieves all the messages saved in the database. If I saved all the messages in the conversation-service that would increase the coupling between the services as any changes made in the message-service will affect the conversation-service as well. It will also decrease the cohesion.

The problem made me question whether my services are too broad and big and need to further create services that handle these specific problems.

I was thinking of creating another service for the above-mentioned example called message_conversation_service which has its own database saved that handles the relationships between these two. Then the client can use this service to retrieve all the messages for each conversation. Is this acceptable when designing and implementing microservices? If not, how do I manage the relationship between the services?

1 Answer 1

3

One of the key aspects of microservices is that they are 'autonomous'. That is, they do not have external dependencies. What you are describing is what I would classify as a 'distributed monolith' which has all the problems of a monolith with none of the advantages.

There's a common misconception that microservices means deploying each endpoint independently. In reality the idea is that you have a set of endpoints or an API and all the implementation dependencies (e.g. a DB) all bundled into a independent and self-contained solution.

This makes the conversation service in need to know about the message service which saves and retrieves all the messages saved in the database.

If you are implementing a microservices pattern ⃰, both of these capabilities should be deployed together. You may not need a 'message service' unless you have a separate need to retrieve messages outside of the conversation, don't expose that as an endpoint. It's OK for it to storing and retrieving messages to just be part of the implementation of the conversation microservice.

I should clarify that there is a lot of literature from (more-or-less) authoritative sources that asserts that deploying each endpoint separately is a defining feature of a microservices architecture. I find this idea to be a little confused and confusing. While deploying each endpoint as a separate container (as an example: containers are not required for microservices) has some useful benefits, if two endpoints share a dependency on a database, they aren't independent and are not separate autonomous services. IMO that idea conflates containerization deployment architecture with the logical architecture of a system. But that's part of the challenge with microservices: all the terms are overloaded and can mean different things in various contexts. When people read 'service' they are thinking endpoints but that's not the right concept of 'service' when talking about microservices.

I found relevant discussion in this article which I think highlights the point I am trying to make:

... far too often I see an overcorrection from large monolith to really small services, really small services whose design is inspired and driven by the existing normalized view of the data. This approach to identifying service boundaries almost always leads to a cambrian explosion of large number of anemic services for CRUD resources. For many new to the microservices architecture, this creates a high friction environment that ultimately fails the test of independent release and execution of the services. It creates a distributed system that is hard to debug, a distributed system that is broken across transactional boundaries and hence difficult to keep consistent, a system that is too complex for the operational maturity of the organization.

There's a link in that section to this video which might be helpful as well.

⃰I think microservices are great but you should understand why you are implementing them. They should be a means to an end. In other words, your goal for using microservices should be something other than 'to use microservices'.

4
  • 1
    "Cambrian explosion of ... anemic services" Yikes! And I thought the late Fred Brooks' carnivores were frightening. Can't wait to see an illustration of ancient blood suckers.
    – J_H
    Mar 2, 2023 at 0:54
  • This makes sense. No need to have a message service since the conversation service is the only one using it. I just watched Charles Haynes presentation and he made some pretty decent points. One of the things that he explains on how to tell if a microservice is too small is if you can't deploy because another service depends on a service, then it might be too small, which I believe fits right in the conversation service and message service. The conversation service needs message service to properly function, as the whole conversation service is based on it.
    – thetruth
    Mar 2, 2023 at 12:40
  • ... It also makes me wonder if there really is any right and wrong in regard to structuring a whole microservice architecture as long as it follows the rules of microservices and I think that is one of the things that I worry about. I mean if a system is scalable and the services can be deployed independently without affecting each other then services are built just right. Another point Charles Haynes made in regard to this is that the size of your microservices should be determined both by your business context and organizational context.
    – thetruth
    Mar 2, 2023 at 12:46
  • @thetruth When writing this answer, I had the thought that the term 'microservices' has kind of fallen into the same realm as SOA: there's so much conflicting advice and the terminology is so unclear that lost some of its meaning. The key thing I think we need to focus on is autonomy, especially around data(bases). Ironically enough, that was the top-end of SOA maturity in the literature. Not having to worry about breaking other team's stuff (or worrying less) is a huge advantage. It gives you a wide berth for evolving your solution on your own terms and timeline.
    – JimmyJames
    Mar 2, 2023 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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