Sharing DTOs – Ways to Share DTO Across Microservices

architectural-patternsArchitecturedtomicroservicespubsub

My scenario is as follows.

I am designing a system designed to receive data from various types of sensors, and convert and then persist it to be used by various front-end and analytics services later.

I'm trying to design every service to be as independent as possible, but I'm having some trouble. The team has decided on a DTO we would like to use. The outward-facing services (sensor data recipients) will receive the data in their own unique way, then convert it to a JSON object (the DTO) and send it off to the Message Broker. Consumers of the messages will then know exactly how to read the sensor data messages.

The problem is that I'm using the same DTO in a few different services. An update has to be implemented in multiple locations. Obviously, we've designed it in such a way that a few extra or missing fields in the DTO here and there are not much of an issue until the services have been updated, but it's still bugging me and makes me feel like I'm making a mistake. It could easily turn into a headache.

Am I going about architecting the system wrong? If not, what are some ways around this, or at least to ease my worries?

Best Answer

My advice? Do not share these DTOs among the applications in any kind of library. Or at least don't do this right now.

I know, seems very counter-intuitive. You are duplicating code, right? But this is not a business rule, so you can be more flexible.

The service that sends the DTO needs to be rigid in his message contract, like an Rest API. The service can't change the DTO in a way that could break the other services that are already consuming the information from the DTO.

When a new field is added do DTO, you only update the other services that consume this DTO if they need the new field. Otherwise, forget it. Using JSON as content-type you have the flexibility to create and send new attributes without breaks the code of the services that don't map these new fields on his actual versions of DTO.

But if this situation is really bothering you, you can follow the Rule of Three:

There are two "Rules of Three" in reuse: (a) It is three times as difficult to build reusable components as single use components, and (b) a reusable component should be tried out in three different applications before it will be sufficiently general to accept into a reuse library.

So, try to wait a bit more before sharing this DTO among the services.