Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
410 stars 173 forks source link

Worker.Extensions.RabbitMQ: How to output a message with headers? #1227

Open mathiasi opened 1 year ago

mathiasi commented 1 year ago

We are currently in the process of migrating from in-process to isolated. First it wasn't really clear as to how to access BasicProperties in the new way but it seems that they can be accessed through context.BindingContext.BindingData. However we seem to be a bit blocked as to how to output a message with headers? It seems like the current implementation can only return a string as per the documentation on https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-rabbitmq-output?tabs=isolated-process&pivots=programming-language-csharp. Previously we used the binding to access IModel like in the samples in https://github.com/Azure/azure-functions-rabbitmq-extension/blob/dev/extension/WebJobs.Extensions.RabbitMQ.Samples/RabbitMQSamples.cs

kshyju commented 1 year ago

@JatinSanghvi Could you help with this question?

JatinSanghvi commented 1 year ago

It may not be possible to output message with headers in .NET isolated function apps. We too suggest binding to an IModel object to users who need to add headers to output messages.

mathiasi commented 1 year ago

@JatinSanghvi how would you go about this? Are you talking about a total custom solution here? Cause the Microsoft.Azure.Functions.Worker.Extensions.RabbitMQ package does not reference any RabbitMQ-library.

JatinSanghvi commented 1 year ago

Hi @kshyju, @fabiocav, I will need input regarding what solution we can provide for this. The support for referencing IModel inside the user function must be added in RabbitMQ extension to cover all scenarios that were not made available otherwise by directly binding to byte[]/string/POCO types. However, IModel has internal states (it's not serializable) and it's not the one that can be assigned the output message directly. Instead, user is supposed to call .BasicPublish() method on it to publish messages (see https://github.com/Azure/azure-functions-rabbitmq-extension/issues/197#issuecomment-1165458553). Personally, I do not think that it fits as an output binding as the user is mostly free to do anything with IModel even including sending messages to a different RabbitMQ queue.

Does it make sense to introduce a new type for output binding in RabbitMQ extension that can be used for passing message-properties like headers e.g., IRabbitMQMessage<string/byte[]/POCO>. Along with the message body, this class can have another member with type similar to IBasicProperties with all properties that the users of RabbitMQ extension are looking for. We can also provide trigger binding support for this type.

fabiocav commented 1 year ago

Does it make sense to introduce a new type for output binding in RabbitMQ extension that can be used for passing message-properties like headers e.g., IRabbitMQMessage<string/byte[]/POCO>. Along with the message body, this class can have another member with type similar to IBasicProperties with all properties that the users of RabbitMQ extension are looking for. We can also provide trigger binding support for this type.

In some cases, it makes sense to introduce something like this. It's ultimately up to the extension and the experience you want to enable. This may benefit from a quick design sync.

mathiasi commented 1 year ago

Any updates on this? We still very much dependent on this in order to move to isolated process.