Search code examples
rabbitmqmessage-queuedistributed-system

Is having a type property in a queue message an indication of a bad design in RabbitMQ?


I’m trying to better understand the nuances of designing a distributed system using queues in general and RabbitMQ in particular.

Let say I have messages like

{
  "id": 12,
  "name": “John”
  "role": “Employee”
}

and

{
  "id": 13,
  "name": “Alex”,
  "role": “Manager”,
  "level": 1
}

Note the role property.

A publisher will send the above messages when each individual completes signing a document. The consumer should do different things based on the role of an individual.

Design Approaches

  1. Should messages go to a direct exchange (without a routing key) and eventually to 1 queue? Consumer need to listen to one queue and consequently it has the responsibility of identifying what type (based on role) of an actor has signed a doc.

  2. Should messages go to a direct exchange (with a routing key) and eventually to 2 different queues? A publisher can publish messages with 2 different routing keys. RabitMQ can handle the routing. The consumer will listen to 2 different queues. This approach removes the need for a role property in a message.

  3. Should this go to a topic exchange (with routing key) and eventually to 2 different queues? This also removes the need to have a role property in a message. In this scenario type of exchange is different.

My question

Is it a bad design when we end up having something like a type (in my example role property) in a message and forcing consumer to listen to just one queue? Or its better to utilize the routing key functionality of RabbitMQ and never keep an identifying property in a message?


Solution

  • I think your example is not good. Role is not a type. It is an attribute of the employee entity. In case there are other attributes to consider to sign a document, such as years of service. Do you have to add different queues? These logics should be completed by the application side. And what the publisher sends is the employee entity, no matter what role it is, or other attributes.

    If there are two types for an order, one is that the user cancels the order, and the other is the user completes the order, then there should be two queues, using different routing key, such as order.cancel and order.finish.