2
votes

Let's assume that I have a couple of MicroServices with each exposing a set of REST end points. Assume that MicroService A is communicating with MicroService B and they exchange JSON data.

This JSON data needs to be Serialized and De-Serialized on both the MicroService A and B. This Serialization logic and the models are going to be the same on both the MicroService code base.

I can reduce this duplication by just moving the model classes into a small dependency and use it on both the MicroServices. Not a problem! This might go against the goal of a MicroService architecture, which is "share nothing". But I feel even more potential problem to address is code duplication. What do you guys think?

2

2 Answers

3
votes

I do not see the point 'share nothing' in this scenario. As long as you will hold your De/Serializer as an Artifact in some nexus, you do not "share" anything, instead you are using an (somehow) external library. If you use e.g. logging, both of your projects will use the e.g. slf4s, but they do not share it, as each uses it separately.

1
votes

There are a number of things to bear in mind when separating out a functionality into communicating micro-services:

Tying of scala versions between server and client

If your server requires specific versions of scala (because, for example, you use a library that only exists for version 2.10), this should not impact your choice of scala version in the client. This points towards the idea of having the classes representing your communication path, as being in a separate project which can be cross-compiled separately.

Tying of libraries between server and client

The less requirements your shared library places on your client code, the better. Even forcing a particular choice of Play server enforces a level of rigidity and coupling between client and server that is best avoided.

The best option is that this library causes a dependency on zero other libraries.

Supporting protocol changes over time

One of the advantages of having separate services is that they can be upgraded and improved at separate points in time. You should always try and have the server support the previous version of your communications protocol, whenever it changes. This allows you to roll back an update easily, and also update the client at a different point in time.

Not allowing backwards compatibility means you need to update both services in lock-step. This not only reduces a lot of the advantages of using micro-services, it also makes it a huge pain to deal with rollbacks, if that becomes necessary.


The universal story here is to enforce as little as possible in the way of choice (scala version, library version, time period when protocol changes must happen) on the client, through what choices are made on the server.

If you can follow this approach, I don't see a problem with using code to enhance the accessibility of talking to a service.