How to gather data from multiple services?


(Dmitri Bodiu) #1

Hi there! I’m going through workshop exercise files, Why is calling _shippingProvider.GetPackageInfo and _customerProvider.GetCustomerInfo? how is that better than just calling those services via http? I remember Udi was talking about services should not expose their data, i.e instead of providing all order history for a specific customer, the OrderHistory microservice will implement IProvideFraudScore and will modify the default score based on the internal data it has. And another question is why ShipWithFedexCommandHandler is placed under ITOPs project? Why it is not part of shipping project? Thanks, and have a great day)

(Sean Farmar) #2

Hi Dimitri,

  1. The idea of using the IProvide pattern is to allow what Udi describes as “engine” components, components that are composing activities and data across domain services boundaries, to use this data to provide capabilities of the likes of search, invoicing…

  2. ShipWithFedexCommandHandler belongs in ITOPs namespace as it is an integration component (does not belong in any domain boundary)

Does that make sense?

(Mauro Servienti) #3

Hi @dmitribodiu,

In the end it’s not really that different, the main adavantage is that it masquerades away implementation details.

The use case modeled in that part of the workshop is intended to demonstrate integration with 3rd parties. In which case services one way or another must expose data. On one hand there are your well designed services and boundaries on the other hand there is one service, the 3rd party one, that simply doesn’t speak your language. Also your well defined information are crossing a boundary leaving your world for something you have no control over.

Mainly because Shipping should not be responsible to talk, from the technical perspective, to the 3rd party. Shipping owns the intent to ship with FedEx, not the technical details about how to talk to FedEx. Given that multiple services are involved in talking to the 3rd party it makes more sense top host it under the ITOps umbrella.

Going back to the interface implementation details, there nothing wrong in reversing the responsibilities, by doing something like:

class ShipWithFedExCommandHandler : ....
   public ShipWithFedExCommandHandler( IEnumerable<IProvideFedExInfo> providers)

   public async Task Handle( msg, context )
      //create empty xml doc
      foreach( var provider in providers )
         await provider.AppendInfo( /* previously created xml doc */ );

      //send doc to FedEx

In the above sample the shipment process knows nothing about info providers, this approach requires, for example, that the order in which providers are invoked is not important.