4

I've been thinking about practicing with a simple Microservice (oxymoron I guess) application and I found an issue I was not able to resolve.

I'll go with a concrete example since the definition of cross-cutting concerns is kinda vague. Let's assume I use some of the cloud MQ providers to set up a communication for at least two services. They might use different queues, different types of messages, etc, but there is still some boilerplate code like creating a request to the MQ, deleting a message, etc. Therefore, I'd like to have this repetitive code stored in one place. On the other hand, I'd also like to achieve the ability to 'experiment' with the services, e.g. if a new version of the MQ SDK comes up, I'd like to be able to use it in one of my services, which is, for instance, not as critical for business.

  1. Create a shared library which would be used by two of the services. Some mapping of the messages might be introduces by the services, as well as configuration of queue, visibility timeout, etc. The boilerplate code will be in one place, which is nice. On the other hand, if I preferred to upgrade this shared library with the new version of MQ SDK, all of the services would start working with the new version as soon as I redeploy them, which isn't the best option IMO.
  2. Simply put the same code in each service. With such approach, if I wanted to upgrade service A, I'd simply change its code and that's it. However, I think it's not the best option.
  3. Have some kind of the package repository and use a package manager like NuGet or sbt. Thus, the library to work with the MQ will be published as a package and will have its own versioning. When upgrading the MQ SDK, one will also upgrade the major version of library and release it to the repo. Services which are interested in it will download the package and upgrade it, others will remain intact.

For me, the third one is the most promising, however I cannot say I faced it in every project I worked with. I assume because it's not easy to set up. I've done some research on that and it looks like in general people prefer something close to the third way.

I've managed to find a similar discussion for Python, and even though I talk mostly about .NET and Java/Scala, I think it's pretty close. I'd like to hear some ideas which are probably closer to the area I work with, however, if one thinks like closing the question as a duplicate, I understand, though I think it could be discussed in more detailed way that it was with Python.

  • Perhaps MEF can help where you can link the catalogues to implementations to represent this versioning without having to go through nuget etc. I don't have a fully fleshed out implementation in my mind, but just a thought... – Achilles Feb 3 '17 at 5:16
2

A design principle for me for microservices is to have each service as decoupled as possible from other services. That allows you to deploy and upgrade a service without worrying about breaking other services.

A black-box library of functionality (your option 3) seems like a viable option.

That being said, I would go with option 2 until you have a good feeling for optimizing later. The O'Reilly book "Building Microservices" recommends applying the DRY principle most strongly within a microservice. The author is not so against copying logic from one microservice to another.

  • Thanks for your opinion, seems pretty reasonable, though it leaves me wondering how often the third option is used. – Vlad Stryapko Jun 15 '16 at 13:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.