Question

I'm working on a big project with easily defined boundaries and domains.

The project includes:

  • Portal (news, articles, encyclopedia, users)
  • Forum (threads, posts, users)
  • Chat (messages, users)

Essentially, if I used the macroservice architecture - I would create 3 cross-communicating services (as listed above) and just have them replicate users, as it's the only shared resource.

.. but I know for a fact that according to microservices architecture - each and every thing in parenthesis (news, threads, messages, users ..) should be a separate service - which will make the whole project more complex and bigger in terms of data - as now I'll also have to replicate user on news, articles, encyclopedia, threads, posts and messages services - essentially having 7 copies of the user (granted, with less columns in most services, but still).

Can someone explain to me which of the approaches to services is better? Macro or micro?

Was it helpful?

Solution

Bottom Line Up Front: The more cross communication each service needs to do, the less likely that you've properly defined the correct boundaries.

When decomposing microservices, you want to minimize the direct dependencies between them. That is done in many different ways:

  • The integration is done in the front-end (i.e. Single Page App) or a near-front-end layer (GraphQL layer)
  • All relevant user claims are built into the user's session token
    • The session token needs to be tamper evident (i.e. signed)
    • Easily validated independently
    • That token should be provided with every call to every service
  • Data references are often transmitted as URLs

With the above requirements on the User session token, it's understandable that JWT is one of the most common standards for user tokens--particularly since almost every language used for microservices supports parsing and validating those tokens. By shifting the requirement of user identification to the session token, you remove almost all reasons to need to look up user information. That leaves your user service to take on the role of managing user information and handling token management. Your single page app, stores the session token and submits it with the Authentication HTTP header for every call to a microservice. In this case, this identifies user service as it's own independent service, and removes "user" from the list of parentheses on the initial list of microservices.

With hierarchical information like "Threads" and "Posts" for your forum srevice, you have to decide if the information is truly independent or not. If the concept of "Posts" was going to be re-used for more than just "Threads", you might have an argument to separate the two. However, I would most likely treat them as part of the same service until you have a documented reason to separate them.

As you break down the list of services you need to implement, you may find that portal is not a microservice and just a feature for the Single-Page-App (SPA).

It seems that your services would be truly independent if you adopted a different scheme for user management, such as the JWT tokens. You may not even need to write the user service if you intend on using managed identity solutions like AWS Cognito which can generate the tokens for you.

OTHER TIPS

I think the additional complexity required by introducing a microservice architecture is only justified when

  • you are expecting a requirement to scale up the services independently, or

  • you want to make it possible to develop and deploy the services independently (maybe in parallel by different persons or teams)

So if you have one of the requirements above, go for microservices. If not, you probably won't need it.

(Of course, this is just a general rule of thumb. There may be more driving factors to consider, but as a first shot this approach may serve you well.)

The most common advice when deciding this is that you should start your application as a monolithic service and then evolve it to microservice over time as you learn the pain points of your application. It's generally a lot easier to develop and manage a monolithic service than a microservice until you get to a certain scalability point when microservice starts to make more sense.

You would not know what would benefit from microservice separation until you reached that point. Don't try to start a project by designing seven microservices simultaneously; that's overengineering and you'll never reach the market if you follow that path. You don't want the additional complexity of managing microservices unless the benefit outweighs the cost.

So the answer to your title question "how grained should microservices be?" is that it should be as coarse as you can afford.

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