8

I have two micro services(ms) ms1 and ms2. In both of the ms there is duplicate reusable code(like hashing/security related/orm/etc). Just FYI this usable code can sometimes maintain some state as well in DB (if it matters by any chance)

There are two ways, I can proceed

  1. Either extract the reuable code as separate library and include in both ms
  2. Create separate ms for this reusable code and expose it as rest end points

If I take approach 2, advantage is I just have to redeploy the ms3 in case of any change. If take approach 1, I need to redploy both ms. At the same time approach 2 will require separate maintenance/resources/monitoring.

Which one is more ideal approach in terms of system design considering hardware resource is not a challenge. I just mentioned two microservicebut in some cases there are more than two ms having duplicate code.

I am not sure what is the criteria which can help me to decide whether to go towards shared library or micro service ?

Update :-

I have got some clarity from below blogs but still have question. Will think and post anew question if required.

https://blog.staticvoid.co.nz/2017/library_vs_microservice/

https://dzone.com/articles/dilemma-on-utility-module-making-a-jar-or-separate-2

user3198603
  • 5,528
  • 13
  • 65
  • 125

1 Answers1

7

Microservices are only one of architectural styles. In some cases it is better, in some it is worse than other styles. If you don't use microservices it not mean that your architecture is not good.

If you still want to have microservices, then none of these approaches (shared library vs. library as a new "microservice") is good.

I'd suggest to consider following.

  1. Microservice approach does not mean, that each end point should be encapsulated into a separate microservice. It is normal, that one microservice provides several different end points. If this is your case, then put your two services into a sinbgle microservice and make them reachable via two different end points. Then it is fine that both of them share some classes.

  2. Microservices should normally have independent persistence layer. If there is a strong dependency on the common persistence layer, check, what was the reason to split them into different microservices. Do they really work with different business domains? Can these service be developed and deployed independently on each other? If not, then may be there is no reason to put them into different microservices and it could be better to put them into a single microservice. Then it would be fine if they share some classes.

  3. A good microservice should be provide functionality for some domain. If you put shared code to a separate microservice, then it may be that your shared "microservice" does not provide any functionality for a domain, but is just a wrapper for utilities. That would be not a microservice.

  4. If you have strong reason to separate your services into two different microservices, then duplicate the code. Each microservice should be independent on the others. It should be possible to replace database and to replace any classes of one microservice without affecting the other one. One normal way to make them independable is duplicate the classes that you (currently) consider as shared. If the services are really independent with the time this duplicated code will change and will be different in each microservice. If you have to change this code in both services simultaneously, then it means that your split is not correct and that what you have are not microservices.

mentallurg
  • 4,967
  • 5
  • 28
  • 36
  • 1
    Re “then duplicate the code“ : from https://stackoverflow.com/questions/48961000/why-shared-libraries-between-microservices-are-bad/48961173#48961173 “certain types of coupling being a strict no-no (like sharing databases or using internal interfaces). However the use of common libraries is not one of those” – Michael Freidgeim May 14 '20 at 07:03
  • @MichaelFreidgeim: No, I don't agree. I don't mean some *external* libraries like Apache Commons. I mean the code that is being developed in the same project. Making a shared library from your own common code have following problem. One Microservice requires particular changes, that affect also your shared library. When you modify shared library you should make sure that this still suites other microservices. Often you have then adjust other microservices because you changed the library. Namely this is dependency. Change in one microservice is not independent on other microservices. – mentallurg May 14 '20 at 10:51
  • 1
    If it is a **common** functionality, do the fixes/ enhancements, that will be useful for all microservices(maintain the code in one place) and update each microservice when it’s ready( it’s ok for microservices to use different versions of the common library). If your new changes are useful for single microservice, clone the code and keep it in relevant repository, because it is not common any more ( but other classes will stay in the common library). – Michael Freidgeim May 14 '20 at 11:20
  • I am using git subtree to share code between different repositories. http://stackoverflow.com/questions/43164316/how-to-share-source-code-library-between-several-solutions-in-different-reposito – Michael Freidgeim May 14 '20 at 11:21
  • This is oversimplified expectation :) In my experience different services have often incompatible requirements to the code that basically look similar. The desire to fit requirements of all microservices that need this library lead often to a huge API with multiple parameters and with multiple flags that specify which mode of work is desired (flag that suites service A, or service B, or Service C). This makes the library not maintainable, every seemingly small change requires huge efforts and correspondingly is expensive... – mentallurg May 15 '20 at 01:44
  • ... That's why often the better way is not to try to fit requirements of multiple miroservices, but to allow each service to have its own copy of such library. On the first glance this may look as duplication of efforts. But in the reality it *saves* a lot of efforts: Efforts to agree each change with each service that uses the library, agree about the release policy, it saves also a lot of testing efforts, because *each* change in the library should be tested in *each* micreoservice that uses it... – mentallurg May 15 '20 at 01:49
  • ... Besides, having such library for all microservices makes release process *slow*, because one needs to agree every change with the others: The others need time to review it, then you need time to reflect they objections or desires, suggest the change again, again review, iterate. Then wait for test result from of each service. Then make changes that broke other services. Iterate. This is not impossible. But it **slow**. Where as one of ideas behind microservices is the desire to release often and as much as possible independently on the others. – mentallurg May 15 '20 at 01:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213891/discussion-between-mentallurg-and-michael-freidgeim). – mentallurg May 15 '20 at 01:54