centiservice / mats3

Mats3: Message-based Asynchronous Transactional Staged Stateless Services
https://mats3.io/
Other
63 stars 7 forks source link

Upon Request, tell service which fields you expect. Service can filter out the fields not needed. #5

Open stolsvik opened 8 years ago

stolsvik commented 8 years ago

Many services will provide several fields in the ReplyDTO. However, some requests might not need everything returned. It would thus be wasteful both in the service to retrieve this information, serialize and deserialize, and for the messaging infrastructure to pass it along.

This can be accomplished with booleans in the RequestDTO, i.e. "includeOrderList".

However, it could possibly be very elegant if the requestor just used a cropped "incomingDTO" class, where the orderList field was not present. If this could be provided to the requested service, we would have a versatile mechanism for such multi-purpose endpoints to include whatever the requester wants.

In a initiation, you could pass the DTO that the terminator expect in the request-call.

In a multi-stage service, the framework would known which DTO is expected by the next stage.

The DTO would be introspected, enumerating which fields was present. This would be sent along with the MatsTrace request structures.

On the receiving side, we could filter the returned DTO before serializing it (e.g. just null out the not-requested fields). This would at least make the messaging infrastructure not have to transport the data. However, the service could also get hold of the fields inside the processor, from the Context object. This would then be an Optional<Set>. If the optional was empty, the expected incoming DTO was not provided upon the request, and hence there was no info of which fields the requestor expects, and therefore all fields would have to be loaded into the Reply DTO. If, however, it was present, the service could check whether "orderList" field was expected, and only if present would it retrieve the orders and put them in the ReplyDTO.

stolsvik commented 6 years ago

One more usage for this, is to evolve/"garden" the full system. If in 2 years time, no-one is actually using the property "fullOrderHistory" of the CustomerService.getCustomerInfo endpoint's ReplyDTO, then there is no point in keeping the code for that around in the endpoint either. However, it is hard to know this kind of info in a distributed system, hindering such gardening.

If one log every message through the system for from-to - and includes the properties employed - then one could use a "rolling 3 months tally" of which endpoints and which properties of the Reply DTOs are actually used.

I just occurs to me that it would also be smart to have some way to see if any property on the Request DTO is actually not employed by a service anymore: This can happen e.g. if a service deprecates a "customerSsn" and instead wants a "customerId", but in a transition phase handles both. When some time down the line every calling service has upgraded to present "customerId", one removes the "customerSsn" from the owning service Request DTO. However, the calling systems might still send this legacy customerSsn field, now not employed at all by the receiving side, maybe even the calling systems must go through pains to find the value - and it would be good to find such unneeded request properties too.