Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Micro services: shared library vs code duplication

Similar questions were asked a few times, but as every use-case can be different I thought it worth to ask it again with the specific case I'm facing with. So, we are developing micro-services using .netCore. Let's call these services ServiceA, ServiceB, ServiceC.

Common entities

If ServiceA calls ServiceC, then ServiceC responds with a JSON content which can be serialized into ResponseC object.

This means, that both ServiceA and ServiceC should know ResponseC class. At this point I see two possibilities. ResponseC class can be in a shared library and both ServiceA and ServiceC should have a reference to this shared library. However I read statements like do not share libraries among micro-services. This leads to an other possible solution. Let's introduce ResponseC class in both micro-services, but then somehow I find this a bit against maintainability, because of code duplication.

Common logic

Both ServiceA and ServiceB communicates with ServiceC. When communicating with ServiceC we intend to have some policy regarding read and connection timeout and regarding the maximum number of retries. These values are configurable and there is also some common parts in the retry logic to be able to read the relevant values from the configuration file and to wrap the http calls. The question is pretty much the same like in the previous case, because I either put these classes into a shared library or I basically introduce the same classes in both ServiceA and ServiceB. These classes are quite simple and generic, so at the moment I cannot imagine, that these classes will change frequently.

So the question is, that what is better in these cases, duplicate code and having independent micro-services or introduce a shared library which makes these services dependent?

like image 650
melonT Avatar asked Jun 26 '18 10:06

melonT


3 Answers

When it comes to model classes, I say duplicate code. The entire idea of using JSON or some other language independent protocol instead of serialized native Java objects (for example) is to avoid side-effects of class changes in one microservice rippling throughout your entire ecosystem. A shared library of model classes locks multiple microservices into a polygamous marriage contract where divorce precipitated by even small disagreements between a pair of members can be very expensive. Service A may require changes to its model that not only are unneeded by Service B, but might be totally incompatible with it.

This doesn't mean that code cannot be shared across different microservices. There's nothing wrong with sharing libraries among different microservices as long as their functionality is limited to addressing cross-cutting concerns. Perhaps your common timeout and retry functionality you mentioned falls in the category. Model classes that do nothing but hold a data representation of a language independent protocol do not fall into this category in my opinion.

like image 200
Gerry Mantha Avatar answered Oct 17 '22 02:10

Gerry Mantha


Of course there is DRY rule in programming. But, as Sam Newman said in his book "Building Microservice": Don't Repeat Yourself inside one microservice.

Common entities: Let's look at your example with ResponseC. Imagine that something in ServiceB has changed so now one of the field from the response have changed - now you have to update each service that uses this shared library, even if the service don't need this changed field. If you had the ResponseA, ResponseB and ResponseC for each service, you didn't had to update each service with the new dependency.

Common logic: Basically the same rules are applied here. However it's common to use some third party libraries for common microservices issues like time-outs and retries. What else I can suggest is to look at service mesh implementation like istio and linkerd. Service mesh will give the possibility to these issue to the infrastructure layer so you can focus on writing business logic.

like image 42
Sergii Bishyr Avatar answered Oct 17 '22 02:10

Sergii Bishyr


I agree with the comments above in preferring duplicating the class code. I went down the road of distributing shared classes via an internal NuGet server and it didn’t work well. The different microservice consumers of the JSON started out using the NuGet class, but soon were asking for changes that would break the others. All consumers eventually ignored the NuGet class and created their own.

like image 42
Brad Irby Avatar answered Oct 17 '22 03:10

Brad Irby