2

I am trying to use some kind of microservice architecture. I am trying to use HTTP and JSON as a communication medium (I know better than to call it ReST).

So, I'm using spring-mvc and I wanted to use a class as a ResponseBody on the called and as a RequestBody on the callee. So it so happens that I can duplicate and mirror the class on both the projects, or create a jar and include it in both.

I see coupling in both cases, the first one is duplicate coupling and the other is (I'm sure it has a name) coupling.

And the Request and Response models are not what the projects have in common. I am using event-driven architecture for both and the events are somewhat similar (kinda exactly the same).

What should I do?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Amanuel Nega
  • 1,899
  • 1
  • 24
  • 42
  • Typically the microservice team will write a client library for their service that you can include in your other service. That doesn't seem to be a coupling issue. – bhspencer Apr 14 '17 at 20:01
  • I suppose the service client library might contain some classes that are identical to those used in the service but that is hidden in the library. – bhspencer Apr 14 '17 at 20:04
  • @bhspencer Both could work, but in my mind, I thought microservice is kinda about having separate deployment plans in the simplest sense? – Amanuel Nega Apr 14 '17 at 20:19

2 Answers2

0

Depending on common libraries is not a contradiction to low coupling with microservices. You just want to make sure that the libraries you are sharing are developed for a specific concern that is independent of that of your services and that it doesn't depend on anything within your services.

Think of that library like you would for a 3rd party library. For example you mentioned that you are using spring - Just the fact that you are using spring in both microservices doesn't mean they are coupled.

That also means you have to version your libraries and leave it up to the consuming microservices team to decide when they are ready to change/upgrade versions. Here is a link for how to create different library versions in java. Also read this link with some general information about manifests.

In java you can use one of two approaches for including a versioned library.

  1. Include a version number in the namespace or interface/class name explicitly. This allows for the classloader to have a unique identification and being able to include multiple versions at the same time easily. (Probably the preferred way).
  2. Use the same name and only include a single version of the jar at a time. This means you have to replace the existing jar dependency with the new one and then adopt any potential changes. Check this great answer.

If your library is a communication client you want to consider supporting multiple versions concurrently at the server side (as to allow the separate microservices teams to adopt to newer versions in their own pace).

Community
  • 1
  • 1
Oswin Noetzelmann
  • 9,166
  • 1
  • 33
  • 46
  • You mean, keep the libraries contained on the interfaces? Or do you mean, use them like any third party library by having versions of the resulting jar. If the update is not necessary to the other, keep using the old version of the library, right? – Amanuel Nega Apr 15 '17 at 03:36
  • Yes, I mean that they fulfill a self contained purpose and are built to be reused (like 3rd party libs). It's important that they do not depend on your microservices. – Oswin Noetzelmann Apr 15 '17 at 05:15
  • I strongly disagree with this, if you are sharing transport classes through a common library a change in the transport class nessecitates a change in multiple microservices. This is exactly the coupling you want to avoid. The only way to mitigate that is by using versioning. – undefined Apr 16 '17 at 07:16
  • Yes libraries, or software in general for that matter, require versioning (a build number at a minimum). Not sure what is there to disagree? – Oswin Noetzelmann Apr 16 '17 at 07:33
  • @Oswinnoetzelmann Can you point out a way to version? Handling multiple versions seems like hell. – Amanuel Nega Apr 16 '17 at 17:27
-1

If your microservice is publishing an interface you want to be especially careful about how you deal with changes. Sharing a communication library is a particularly dangerous way of coupling these two services togeather especially as it gives the illusion of consistancy between services.

If you want to share an interface you have to do at least the following (IMO):

  • Version your microservice, and support all previous version of your transport payloads. (you want to do this anyway)
  • Ship the actual transport contracts as a versioned package (so that the consumer is not forced to use the latest contracts) I think in java you might use maven for this (but im not a java person)

This is really important as it means two things are possible

  • A service can change its interface at will without needing to worry about downstream code dependancies (assuming it follows versioning rules)
  • A consumer has the choice about when to update its communication wrappers, and is never overtly compelled to build and ship a new version in response to a change in one of its dependancies.

For some more info on versioning check out my blog. Microservice versioning; How to make breaking changes without breaking stuff

undefined
  • 33,537
  • 22
  • 129
  • 198
  • The author asked if sharing code libraries between services is adhering to microservices pattern, not how to design dependencies between APIs. – Oswin Noetzelmann Apr 16 '17 at 07:43
  • @oswinoetzelmann i think you should re read the question. The OP is asking about sharing a class for responsebody and requestbody. Thats a transport schema NOT a tools library like springmvc – undefined Apr 16 '17 at 07:48
  • I never said tools library. A library containing responsebody/requestbody is still a library and can be treated like other external dependencies. – Oswin Noetzelmann Apr 16 '17 at 08:14
  • @oswinnoetzelmann thanks for looking out, I agree with you! I think I should treat the libraries like third party libraries. I agree with you too, I need versioning. But I don't think Oswin ment other wise. If the communication on one service changes, the other must also change. I think that is a must! – Amanuel Nega Apr 16 '17 at 17:23
  • @amanuelnega can you please clarify your question, Are you asking about the class you use to searialise/deserialise the request/response or about the spring library – undefined Apr 17 '17 at 02:06
  • about my own libs, why would I bother about spring libs? – Amanuel Nega Apr 17 '17 at 09:57
  • @AmanuelNega does your 'lib' contain information about the request content? – undefined Apr 17 '17 at 09:59
  • it does... Versioning is a must, if sharing a library is the way I choose to go, what other choice do I have here anyways. That is what I meant to ask – Amanuel Nega Apr 17 '17 at 10:09
  • @amanuelnega Like I say in my answer you should make sure its a lose link like a package or you will be tempted to do things which wont work. There are other options like using swagger and codegen or just hand coding the consumption schema you actually use. – undefined Apr 17 '17 at 10:25