Should I share models across multiple microservices?
Asked Answered
H

2

23

I'm in the analysis phase of a big project, that will be created with a micro services architecture. I am pretty confident that (at least for the next 3 years to come) the whole codebase will be written in TypeScript, and most of the models will be used between these services.

I'm planning to build this with micro services since each module will be a separate API that will have its REST endpoints for dealing with the tasks regarding its responsibility. For example the Identity service will handle the registrations, authentications, tokens renewal etc...

I'm planning to create each service as a standalone NestJS project. With its repository, package, dependencies etc...

But I have a doubt:

Should these services declare each model internally? Even though it might be the same model declared in another service? This might lead to a lot of code duplication across projects, right?

If they don't, and they should define a readonly subset of model, with only the properties they need, which one would be the best way to keep changes to the subsets across the different services when the "source" model changes? Let's say that service A defines model X, and service B uses a subset of X called X1 and service B uses another subset of X, called X2. Whenever a property might change (being deleted, change type, name or other) which one would be the best approach to keep this change in sync across each project when these projects might be 10, 20 or more?

I'm confused because for what I know, a micro service should be independent and have everything that it needs to function, so following this logic leads me to think that the service should re-declare the same copy or subset of the original model, living in another service.

But from the code duplication perspective, this seems kind of a suicide, since for the first year I'll be the only one working on these projects.

I know that a micro service architecture is more fitted for a team of developers, but the team will come, so in the near future there might be 3/4 people working on it, and each one will have a couple of services to maintain and develop.

Thanks in advance to anyone willing to help me solving this doubt!

Hideandseek answered 14/5, 2021 at 14:9 Comment(2)
Just to clarify, why do you need to share models? Will these different services be using the same database?Schuller
Nothing is decided yet, but they will be using the same cluster, not sure (don't think so) that they will be actually using the SAME db inside the cluster. But with models I mean for example a DTO that a service might use to communicate with another or a DTO that a service might output as response to another...Hideandseek
S
23

First of all, I would like to state that one of the main ideas behind microservices is separating responsibilities.

You can share libraries amongst the services (please read this). Also you can expose some representational objects (e.g. Protocol Buffer messages if you are using gRPC). But if you are planning to integrate different services with a shared database, this is not in line with a microservice architecture. Because you are using a database as an integration mechanism between different components of your system.

Having your services depend on each other is something you have to minimize if you cannot prevent it altogether. Availability of your services suffer and you are introducing points of failure to your system.

I think this presentation by Martin Fowler might be useful as well to put things into perspective.

Schuller answered 15/5, 2021 at 12:58 Comment(0)
T
27

The whole point of microservices is that they can change and scale independently. Sharing those models will force those services to iterate together, and will enforce strong coupling (bad).

To deal with shared domains in a microservice architecture, keep you binding to a minimum. When service B is using the output of service A, only map the bits that you need for service B. service B should have its own independent model which only cares about the things from service A that B cares about. That way when something else changes service A's model, service B doesn't care.

If all of these things are living in the same database, you don't have a microservice architecture, you have a monolith. Monoliths aren't necessarily bad, they have real advantages by having a consistent internal domain, they just have problems once they get too large. But if you've already structured your database in this way, it's probably easiest to build your software to match it.

Tagmeme answered 14/5, 2021 at 17:32 Comment(0)
S
23

First of all, I would like to state that one of the main ideas behind microservices is separating responsibilities.

You can share libraries amongst the services (please read this). Also you can expose some representational objects (e.g. Protocol Buffer messages if you are using gRPC). But if you are planning to integrate different services with a shared database, this is not in line with a microservice architecture. Because you are using a database as an integration mechanism between different components of your system.

Having your services depend on each other is something you have to minimize if you cannot prevent it altogether. Availability of your services suffer and you are introducing points of failure to your system.

I think this presentation by Martin Fowler might be useful as well to put things into perspective.

Schuller answered 15/5, 2021 at 12:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.