Question

I just started thinking about building a microservices architecture for learning purposes. I understood that microservices are split, and they should be independent, even when storing data, but what is the real application of it? Most data isn't independent, and is relational in some way, even when using non-relational databases.

My starting idea is a basic app where someone can watch something, let's say a TV serie, have an account with a profile, and can comment and like that TV serie.

The idea is to divide everything in the two following services:

  • User service, which basically means authentication and storing users data;
  • TV series service, which stores TV series data, episodes, links and other blah blah;
  • Streaming service, which handles video streaming, but let's not talk about it.

Obviously, for a correct independent microservices architecture pattern, we should split databases.

Now, my questions are:

  1. Let's say we use JWT for authentication, so it's stateless, and TV series needs authentication to perform some actions. Should the TV series service implement authentication too? Should they check for your JWT token, or should they call the User service to handle authentication?
  2. Where should you then store things that a user does - like comments, and likes, if there is a relation between the two databases? If having a single shared database is an anti-pattern, and calling a microservice from another one is an antipattern too, how should you handle a comment? In what database should you store it? And then, how would you do a query which gets "all comments of a specific user" if you can't join or aggregate data between databases, because they're split? Is manual aggregation worth doing?
  3. Would this approach benefit of an API gateway? I can't understand why and what API gateways are. Though I understood that, someway, they can help joining responses of two microservices.
Was it helpful?

Solution

so what you would often do in such a situation is introduction of API Gateway. The UI doesn't want to know that there are 3 services that it needs to talk to. There are 3 of them now. Perhaps tomorrow the backend team will decide to split one of them into 2. That's up for them to decide but this should not need any updates in the UI. So what you have is API Gateway. The UI only ever talks to API gateway. Now the API Gateway has a few goals:

  1. validate the body of the request. if the body is fucked up, it doesn't make much sense to propagate it any further.
  2. decode JWT. Again, if JWT is missing or is invalid, it doesn't make much sense to propagate the request any further. In the same time, all the services behind the api gateway will be interested in who made the request, so it would be beneficial for API Gateway to forward the decoded JWT to them in one way or another. But yes. This will probably call the user/authentication service. Usually this is pretty simple if you use some of-the-self authentication service like Auth0 or AWS Cognito or something. Your probably don't want to implement your own user service. There are a lot of ready-made solutions out that ready for grabs (oh, the perks of micro-services)
  3. forward the request to the microservice that is actually going to handle the request, so the TV series service, or the streaming service.

Note that most cloud platforms already have some service for defining API Gateways. On AWS for instance you have a service that is literally called "API Gateway" and it does all these things and many more if you configure them.

As a result a half of your application comes in the form of managed services provided by the cloud or 3rd party services that you find on the internet. You don't need to decode jwt, because it comes to you already decoded.

In the initial stage at least I don't see any problem with storing the comments and likes in the same db as you store the TV shows. Still, you don't need there anything more than just a user ID that you receive from the decoded jwt. But sure, you can store that in a separate service and a separate db as well if you like. Then you will have a table in a db that states the ID of the show, the ID of the user and the comment.

Note however that in the long run you want to keep everything "eventually consistent". So what happens if a user deletes his account? What if you delete a TV show? You probably want to trigger some events that will update the data in your comment microservice. This leads to the event-driven architecture etc.

all in all, microservices make a lot of sense, but there are a lot of ways they can communicate with each other and your data storage depends on their communication. Is it a message queue? a pipe? an event? a direct http call? do you have a sidecar for retries? all these relate to different architectures and may lead to different ways of data arrangement

Licensed under: CC-BY-SA with attribution
scroll top