0

As I have been able to verify, in MassTransit with Azure Service Bus, each type of object consumed by a "Consumer" generates a Topic for that type regardless of whether it is only consumed in a specific "receive endpoint" (queue). When sending a message of this type with the "Send()" method, the message is sent directly to the "receive endpoint" (queue) without going through the topic. If this same message is published with the "Publish()" method, it is published in the Topic, and is forwarded to the receive endpoint (queue) from the corresponding subscriber.

My application uses a CQRS pattern where the messages are divided into commands and events. Commands use the send-receive pattern and are therefore always dispatched in MassTransit with the "Send()" method. The events, however, are based on the publish-subscribe pattern, and therefore are always dispatched in MassTransit with the "Publish()" method. As a result, a large number of topics are created on the bus that are never used (one for each type of command), since the messages belonging to these topics are sent directly to the receiver's queue.

For all these reasons, the question I ask is whether it is possible to configure MassTransit so that it does not automatically create the topics of some types of messages consumed because they will only be sent using the "Send()" method? Does this make sense in MassTransit or is it not possible/recommended? Thank you!

Regards

Edited 16/04/2021

After doing some testing, I edit this topic to clarify that the intention is to configure MassTransit so that it does not automatically create the topics of some types of messages consumed, all of them received on the same receive endpoint. That is, the intention is to configure (dynamically if possible, through the type of object) which types of messages consumed create a topic and which do not in the same receive endpoint. Let's imagine that we have a receive endpoint (a queue) associated with a service, and this service is capable of consuming both commands and events, since the commands are only dispatched through Send(), it is not necessary to create the topic for them, however the events that are dispatched via Publish(), they need their topic (and their subscribers) to exist in order to deliver the message and be consumed.

Thanks in advance

1 Answers1

1

Yes, for a receive endpoint hosting a consumer that will only receive Sent messages, you can specify ConfigureConsumeTopology = false for that receive endpoint. You can do that via a ConsumerDefinition, or when configuring the receive endpoint directly.

UPDATE

It is also possible to disable topology configuration per message type using an attribute on the message contract:

[ConfigureConsumeTopology(false)]
public interface SomeCommand
{
}

This will prevent the topic/exchange from being created and bound to the receive endpoint.

While I can understand the desire to be "pure to the CQRS mantra" and only Send commands, I'd suggest you read this answer and take it into consideration before overburdening your developers with knowing every single endpoint in the system by name...

Chris Patterson
  • 28,659
  • 3
  • 47
  • 59
  • 1
    Thanks @Chris, the solution works very well. I agree with you that the use of "Publish()" is simpler and cleaner, but I am considering this option because it "forces" the development team to have functional knowledge of what it is doing, having to know perfectly if what they want to do is send a command or publish an event. Thus, if a developer tries to publish a command, since its topic does not exist, an exception is thrown, reinforcing the concept of "a command is sent to a specific recipient (send-receive pattern)". Thank you very much for the help as always, it is a pleasure. Regards – Borja Fernández Apr 12 '21 at 16:35
  • Hi @Chris, can you check the edit that i made in the question? Thanks a lot! – Borja Fernández Apr 19 '21 at 08:56
  • 1
    You can't _selectively_ enable binding on a consumer-by-consumer basis. Also, putting all your consumers on a single receive endpoint is discouraged. – Chris Patterson Apr 19 '21 at 12:03
  • In our application, a queue (receive endpoint) per service has been defined, regardless of the number of consumers and / or types of message it receives. According to your previous comment, this is discouraged, so what is the correct approach to define the different receive endpoints of a service? one per consumer? – Borja Fernández Apr 19 '21 at 18:38
  • Hello @Chris, I'm still confused with this issue, about what is the best approach to define receive endpoints. Can you help me please? Sorry for the inconvenience – Borja Fernández Apr 21 '21 at 21:42
  • I already answered above, you can't selectively enable topology configuration per-consumer. – Chris Patterson Apr 22 '21 at 13:26
  • Hi @Chris, sorry for the confusion. I have seen your answers, and what I am looking for is another alternative, that is close to what you consider best. After reading your answers I assume that I will have multiple receive endpoints per service, and the question is: what is the best strategy to create receive endpoints for each microservice? One per consumer? Any recommendations about how many message types a consumer should process? Since I have to rethink the approach, I would like to agree on it with you. thank you very much! – Borja Fernández Apr 22 '21 at 20:23
  • 1
    Generally, I use separate receive endpoints for each consumer. That is the default behavior when using `ConfigureEndpoints`. I have update the answer with some additional information on configuring consumers and the message types. – Chris Patterson Apr 22 '21 at 21:22