This shows you the differences between two versions of the page.
technology:domainmodel:boundedcontext:modelintegrity:customersupplier [2013/01/31 13:28] rtavassoli created |
technology:domainmodel:boundedcontext:modelintegrity:customersupplier [2013/02/01 16:21] (current) rtavassoli |
||
---|---|---|---|
Line 8: | Line 8: | ||
* published services by the supplier ((and a wsdl)) the customer can use((pull)) | * published services by the supplier ((and a wsdl)) the customer can use((pull)) | ||
* published events of the supplier the customer may consume((push)) | * published events of the supplier the customer may consume((push)) | ||
+ | ==== Integration via Database Views ==== | ||
+ | This is probably one of the most primitive ways of integrating contexts, but also one of the easiest if the team is small and the contexts share a database or database server. The contract contains the following | ||
+ | * Database((Kind, Version)) | ||
+ | * Connection Information((Connection String)) | ||
+ | * Authentication Information((Username/Password)) | ||
+ | * View names | ||
+ | * Field names and Types | ||
+ | * Description of the views and fields | ||
+ | * Invariants maintained for the data | ||
+ | Anyone interested can acces the views, either by polling data from them regularly, integrating the view data directly in their own read models((direct joins if possible)) or any other imaginable way. | ||
+ | \\ \\ | ||
+ | The advantage of this type of integration is fast and seemles //immediate consistency//. If you need the suppliers data to incorporate information in the read model inside your own domain, you can do so directly by joining your own tables and views with the suppliers views. No need to poll the data first or cache it yourself. | ||
+ | \\ \\ | ||
+ | The disadvantage of direct integration of the suppliers views in the customers read model is that the customers services depend on the availability of the suppliers services. Another disadvantage is that direct integration is only possible if the suppliers and customers views share the same node. If not, some sort of replication is required. | ||
+ | \\ \\ | ||
+ | If the supplier data is sharded, and there is no one-to-one sharding between customer and supplier, direct integration via replication and synchronization schemes probably doesn't make much sense. There was a reason for sharding, and replicating the supplier data from all nodes to each of the customers nodes would make the original decision obsolete to some degree. | ||
+ | \\ | ||
+ | {{ :technology:domainmodel:boundedcontext:modelintegrity:customersupplieronseparatenodes.png?nolink |}} | ||
+ | \\ | ||
+ | In a situation like this the customer will probably poll the supplier, placing its own services on each of the suppliers nodes which can satisfy the requests by going tho the published views. The customer can poll regularly and cache data((making it less dependent on the suppliers availability)), or poll on demand. | ||
+ | \\ \\ | ||
+ | Simple applications with no necessity to shard and which share one database server can benefit from the simplicity of this type of integration. More complex architecture requires more complex solutions, of course. | ||
+ | ==== Database Integration is simply a Polling Solution ==== | ||
+ | Actually, this type of integration is conceptually exactly the same as polling via a query service. You poll the suppliers tables and views for data. Only that you can optimize polling for lists by being allowed to join directly, i.e. you **use the database engine to optimize the querying of the supplier**. In both cases the data you are obtaining from the supplier is quite current((assuming the supplier has transactionally consistent data)), and you always have the additional possibility of caching polled data. | ||
+ | ==== To use Database Integration or not to use ==== | ||
+ | As always, it depends. If you can always rely on the possibility of integrating via the database, go for it. Actually, if it is a possibility in the current situation, go for it. If things change, move to a different polling solution or maybe even to a push solution. But if there is no need for a more complicated and less consistent solution, you should not make that move right away. | ||
+ | \\ \\ | ||
+ | The implementation of the read model will have a dependency on the available integration technologies with supplier contexts- that's a real drawback. A simple salvation is to wrap the customers read model with an abstract view representation. That view can then be built either by direct database integration, by pulling date from the supplier or by having data pushed from the supplier: | ||
+ | \\ | ||
+ | {{ :technology:domainmodel:boundedcontext:modelintegrity:customersupplierintegrationabstraction.png?nolink |}} | ||
+ | \\ | ||
+ | If you now choose to directly integrate through the database, changing that decision later will only result in you having to change the way the abstract view is //fed//. If you move from direct database integration to a push or pull solution, you will also move to an eventually consistent representation of the suppliers part of the data of the read model. That may or may not be something to consider. If it is, you can //add// information to the read model. You could | ||
+ | * Have time-stamps per read model to represent how recent the data is. That information can either be displayed to the user in the UI, and/or application services using that read model may have contracts stopping them from using data that is too old, | ||
+ | * Invalidate the read model if you have not received data within some defined time-span. If the UI or an application service tries to access that data, an exception will indicate that the supplied data is out of date. | ||
+ | In either case, the read model itself can use the abstract view and not care about the up-to-dateness of the data. **Additional** mechanisms will be put in place if stale supplier data becomes an issue. |