'In Event Driven Architecture, should commands be published to topics in the same way as events?
As a rule we publish "things that have happened" as events to a Kafka topic, and when we want to perform a command we call an API.
Is there anything wrong with publishing a command (e.g. create invoice) to a topic...and having the invoicing service subscribe to that topic and act on the commands as they're consumed?
Or more generically...is it ok to use Kafka topics for issuing asynchronous commands, or should it only be used for publishing "something that happened" type events?
Solution 1:[1]
A year later and I'm here to share my thoughts :).
Issuing a command IS "something that has happened". A command could then change the state of the system and events would be generated. It could also fail, so you would generate an event for the failure.
A public topic for commands would act exactly as a Rest endpoint. With the difference that it is executed asynchronously. This means that you would need to listen for the events that have occurred related to the command by a command id to figure out the outcome. You would also need to take into account that the command could be executed quite later if the service is unresponsive. The benefit you get is the asynchronous execution, you don't need circuit breakers and such.
Not sure what generate invoice includes in you question, but if it would just generate a pdf and perhaps email it, it seems like it's the best approach to send a command on a topic and let it execute whenever it's possible.
Some things to keep in mind here. You should post command messages related to same entity in one partition, as ordering is usually important. The message producer would need to keep in mind the topic partitioning scheme. If you have multiple producers you might be better of with a Rest endpoint to post the messages in the right partition. A bad choice would be if you bundle this endpoint within the consumer service as then you would lose the asynchronous behavior.
There might be more issues to address depending on the use case, but in general I would do what is simpler in the beggining that fulfills the requirements. You could refactor this later without actually breaking the clients to the service.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Bojan Milenkoski |
