architecturesoftware-designreusability

Should I share models across multiple microservices?


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 in solving this doubt!


Solution

  • 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.