2

Let's say you have an app like Facebook, where each Post can be tagged with a Place. Now, the whole social app backend api (basically the whole client api) is built using nodejs + postgres. But the Places autocomplete is a custom API that is built in Golang for example.

Since the Places API is essentially based on a stateless DB (using postgres) cause it just stores information that is not to be manipulated by user, it makes sense to put it in its own micro-service.

So, it kinds of makes sense to have the following architecture :

Service A - the main client api / backend. In this service I can Like a post, follow a Friend, and post new Posts.

Service B - will have all the Places information and API. That means it will have tables with cities and countries, and expose an API to retrieve this information.

So if a user posts a new Post in London, Service A will handle this action and create a record in its db inside table "Posts" , where one of the columns will have the id of London (which sits in Service B's table).

Now, next time I want to Get that post, I will only have the place's id, but obviously we would want to show the information of that place (city name, country name, etc...).

It means that for an endpoint of "getPost(id = 2)" in Service A, we will have to join the Places tables from Service B. And that's the problem. Microservices should ideally not have any inter-communication between them that would constitute unwanted traffic load. Frankly, I'm not even sure how and if that's even technically plausible.

The alternatives would be to have a monorepo with project Places in Go, and the Main project in nodejs, with the same DB, or with 2 databases.

I am unable to weigh correctly the pros and cons and the probability of those alternatives, and would like to understand what is usually done in cases like this?

** P.S - Regardless of whether it would end up being Monorepo or micro-service architecture, I intend to use Docker + Kubernetes.

1

Shared entity is a very common problem in microservices. Theorists of microservices argue that there shouldn't be any shared entities and it's a bad design if you have them But unfortunately that's a very common case. since a storage of a microservice is only accessible by that particular microservice hence there is no other way to access it and for shared entities multiple microservices need to be contacted. there are three ways.

  1. Have Back-end 4 front-end service design where a request is made to BE-FE service which in turn would contact Posts microservice and Location microservice. You need to have some sort of tag/key that relates the Post to location. this BE-FE service would create the final PostWithLocation returned to the caller. Callers only call these BE-FE services layer which is the first layer. this first layer of microservices would contact 2nd layer microservices (posts, locations, likes etc)

  2. Post service retrieves the record and contacts location service to complete the PostWithLoacation. If you have a lots of shared entities then you need to be careful you might end up with a complex interaction of microservices

  3. Move the task of combining these different pieces to the front end. The front end would decide which microservice to call for which pieces. usually you have reverse proxy/gateway which hides many of these microservices so front end only contacts one set of apis instead of individually contacting each microservice.

That's all I can think of. Hope it helps you to decide.

4
  • thank you for the answer. I'm still unclear though on a few nuances here, it seems that my options here are all less than ideal. If we go for micro-services, and communicate via gRPC between them to "complement" information that we need, it'll result in traffic load. If we move that "puzzle assembling" for the Client/Front (mobile app in my case), that would result in multiple API calls, which will increase response time for client, and would still constitute a load on traffic, right? However, with monolith, it will be hard(impossible?) to make two projects in different languages.
    – BinaryVeil
    Feb 9 '20 at 6:40
  • 1
    Or, with monorepo, both using the same db, will end up in coupling of two independent components
    – BinaryVeil
    Feb 9 '20 at 6:41
  • it will be quite a problem if you have microservices that share the database. The sort of independence you get of modifying one microservice without modifying other would be no more. for puzzle assembling.. you can have concurrent calls from BE-FE or even from javascript. so the network call time would be the time of the slowest call not the total of all the calls. Feb 10 '20 at 5:26
  • there is no one answer. As a designer you have to see what works best for your project Feb 10 '20 at 5:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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