MDriven has a clear separation between the application tier and the persistence tier. These tiers are commonly put on different network hosts. And when they are on different hosts we need to communicate between them over the network.
This network communication will include request for:
- Searches in persistence storage
- Access to object content of specific objects
- Finding if anything has changed since last
- Updates of changed objects
- Group fetch given ViewModel knowledge
These different needs has different details in their requests and responses – and it all boils down to an api that use a strongly typed object graph of data.
20 years ago we might have used Remote Procedure Calls to implement this, or maybe DCOM, but then Microsoft came up with Windows Communication Foundation – WCF. The good thing about WCF was that it was very configurable – meaning that you had the basic need set up – the api to communicate over – and then you could use configuration files to control the technical aspects of HOW the transport from point A to B should be done.
WCF sounded great and we started to use that 2009. It allowed us to have 1 implementation and still be flexible to let you decide if the transport should be over TCP or HTTP or HTTPS and if the traffic should be encrypted etc.
Now it is almost 2019 and .net Standard and .net Core are hot topics. The world has consolidated around REST style communication over HTTPS and no one really thinks very much on the need for something else. Why bother add configurability to something that always will be the same? This is probably the reason why Microsoft now ditches WCF and does not move it along into .net Standard whole heartedly (you can call WCF services, but you cannot implement a WCF service with .net Standard 2.03).
MDriven now needs a new way to communicate and that way is WebAPI over HTTPS – this is where the industry is today and we gladly follow.
But the technical aspect of communicating from point A to B is not very exciting. As long as it is secure and not slow – it can be anything.
The interesting part is really how we fold down the object-graph we need to send into to a transportable stream. This is called SERIALIZATION.
The standard way to serialize parameters to and answers from WebAPI services is JSON, but there are also other hot implementations on how to serialize data like Googles protobuf.
When implementing MDrivens new serialization format we had to make the choice on what serialization format to use.
We did not choose JSON and this is why:
- Data type precision loss – byte, int32, int64 all translate to Integer – that then desterilizes back to int64 (same problem with float types). This causes a lot of problems in downstream handling of data – the types are there for a reason and we need to keep the precision. We could invent wrapper objects to keep type fidelity but that would defy the purpose of JSON.
We did not choose protobuf and this is why:
- Limited support for untyped transport – List<object> is not handled even if object is a well known type (like int or datetime). This is problematic for us since we follow the UML model that you have created – and for us a class has a list of attributes that can be of any type – as long as you have a AttributePersistenceMapper that knows how to store it. We could treat the transport format as the persistence format – but today we defer persistence knowledge to the persistence tier so we need to be able to “just get the object content over the wire” so that we can interpret how a chosen persistence mapper should persist the values.
The thing that is left is to use the DataContractSerializer – this is actually the same serializer that is used by WCF – so as it turns out everything change and still stay the same.
To use WebAPI communication instead of WCF you use the new PersistenceMapperWEBAPIClient (MDriven.Net.Http.dll) instead of PersistenceMapperWCFClient. And on the server you subclass the public abstract class MDrivenPersistenceController<T> : ApiController (MDriven.Persistence.WebApi.dll).