Domain Driven Design with Web API extensions part 5: domain events between independent systems
November 5, 2015 1 Comment
Introduction
In the previous post we looked at a solution on how elements of a .NET solution can communicate with each other using a mediator. The mediator keeps the publisher decoupled from the subscribers. Also, the mediator won’t have any knowledge of the event handlers, their exact types and what and how they will handle the messages from the domain objects.
The solution helps the email sending event handler read the domain event in case a user added a new or updated an existing load test. In this post we’ll direct our attention to messaging between independent applications. We’ll ultimately simulate that a financial application also wants to be notified of the load test domain events in order to calculate the monthly profits.
Well, in fact this financial app will only be a C# console app with no logic – we definitely won’t build a full-blown application just for that purpose, that’s not the point of this exercise. We’ll only see a way to communicate between applications.
In this post we’ll look at some theory. The upcoming 2 posts will put the theory into code.
Messaging
How can we solve this task? On one side we have the web suite DDD demo application and on the other side there’s the financial application waiting for new and updated load tests. This is not a new problem in software architecture and there are multiple possible solutions. Most solutions involve some element that sits between the communicating parties, much like the mediator between the Timetable domain and the emailing domain event handler.
Here’s an incomplete list:
- Public API: the financial application can have a public API where other parties can send in their message. In this case we can register an additional listener in the mediator and the listener pushes in the load test data into the API. Our very DDD project has a public API as its ultimate consumer layer. Therefore you should be able to build it based on what we’ve seen if the public API solution sounds appealing to you. An important characteristic of this approach is that the external application doesn’t need to actively wait for the domain events – called a pull -, instead they are passed to the API by the event handler into some API enpoint – called a push.
- Database tables: the financial application can periodically check a certain database table and act upon new unhandled messages. The database table can be filled out by another message handler. We looked at this type of solution in this series dedicated to Windows services. In that demo a Windows service was monitoring a certain MongoDb collection – similar to an SQL database table – where new records were added by an independent application. The Windows service acts upon all new records. This is an example of polling where the subscriber periodically checks for the presence of new messages. The messages are pulled by the subscriber.
- Message queues: message queues are applications that are designed to accept a large number of messages. By “a large number” we mean tens of thousands per second or even more. These applications are often equipped with channels so that subscribers can filter out the messages according to their topic. There are many types of message queue applications out there, both free and paid. We’ll ultimately look at one of them in this extension series. We’ll set up a local message queue that the financial application can pull messages from. This also reveals that subscribers need to poll the channels – or topics – of the message queue, i.e. this is also a case of pulling
- Service bus: this is the most complex solution. Service buses can also handle a very large amount of messages like message queues. The most significant difference between service buses and message queues is that service buses push the messages to the subscribers. The messages are stored in message queues and usually have a best-before date on them. If the subscriber doesn’t pull the message before that then it’s deleted. The service bus on the other hand pushes out the message to all registered subscribers. A good example is the applications on the various smart devices that show you that you have a new message on the screen. E.g. the WordPress mobile application shows a message on the screen whenever a user comments an article. Each mobile that has the WordPress application is a subscriber. I don’t know for sure how the WordPress app receives these message but I bet that there’s a service bus at play. It would be very energy consuming for an application to continuously monitor a message queue.
Message queues and service buses have their own particularities. If you think that you need some type of messaging system to link independent components then you as an architect will need to review what they can do for you. There’s a very good and concise article the describes the characteristics of the MS Azure message queues compared to the Azure Service Bus here.
Another popular service bus implementation is NServiceBus. Amazon has a couple of messaging solutions but I’m not aware of any service that matches the requirements of a service bus.
Message queue examples
Here’s an incomplete list of examples of message queues out there:
- RabbitMQ: this is the solution we’ll employ in our demo. There’s a series dedicated to RabbitMQ on this blog starting here. If you are completely new to messaging then you can read through the first couple of posts in that series to get the initial idea and learn the most important term.
- Amazon Kinesis: a very powerful message queue from Amazon Web Services. It is a paid resource so it’s not very good to use in a demo like this. However, I have a series dedicated to Kinesis .NET starting here if you’re interested.
- Azure queue: the Azure equivalent of Amazon Kinesis
- MSMQ: excerpt from the MSMQ home page: “Message Queuing (MSMQ) technology enables applications running at different times to communicate across heterogeneous networks and systems that may be temporarily offline. Applications send messages to queues and read messages from queues.”
- ZeroMQ: another message transport solution for distributed applications. Read the basics here.
- WebSphere MQ: a message queue by IBM
In the next post we’ll start setting up RabbitMq on the local computer. Until then your homework is to read the first 2-3 posts of the RabbitMq series referenced in the list above so that you get familiar with it – unless you’re already have experience with it.
View the list of posts on Architecture and Patterns here.
Pingback: Domain Driven Design with Web API extensions part 6: domain events with RabbitMQ | Dinesh Ram Kali.