Message identity and IQueueMessageWithId
The IQueueMessage
interface doesn't contain any properties so you can define your message in any way you want. But using IQueueMessage
means that the system won't have any knowledge of message identity. The system won't compare two messages to see if they are identical to prevent duplicates in a queue.
If you need to ensure that a queue never contains duplicates of the same message you should instead use the IQueueMessageWithId
interface.
The only property that you're forced to have on your message class is the Id
property. What the id should be depends on your queue. If you want you can use a combination of values in the implementation of the property. The property is allowed to return null
so you can have messages in the same queue where some have identity and others don't.
If we take the SendOrderConfirmationQueueMessage
from the example in the Overview we can define it like this instead:
[Queue("send_order_confirmation")]
public class SendOrderConfirmationQueueMessage : IQueueMessageWithId
{
public string? Id => OrderId;
public string OrderId { get; set; }
public string Email { get; set; }
}
By doing this the system will ensure that if we already have a SendOrderConfirmationQueueMessage
message for order with id 123
we will never allow duplicates to be enqueued. If someone enqueues it again we'll instead update the existing message rather than adding another one. This is true regardless of which status the message has.
Other queue systems has a separate deadletter queue where failed messages are placed which can allow duplicates to still happen. But if we have a message for order 123
in the Error
status and someone enqueues a message with that id the existing message gets updated and the status is set to Pending
again. Read more about message statuses here.