Azure Service Bus output binding for Azure Functions
Use Azure Service Bus output binding to send queue or topic messages.
For information on setup and configuration details, see the overview.
Important
This article uses tabs to support multiple versions of the Node.js programming model. The v4 model is currently in preview and is designed to have a more flexible and intuitive experience for JavaScript and TypeScript developers. Learn more about the differences between v3 and v4 in the upgrade guide.
Azure Functions supports two programming models for Python. The way that you define your bindings depends on your chosen programming model.
The Python v2 programming model lets you define bindings using decorators directly in your Python function code. For more information, see the Python developer guide.
This article supports both programming models.
Example
A C# function can be created using one of the following C# modes:
- In-process class library: compiled C# function that runs in the same process as the Functions runtime.
- Isolated worker process class library: compiled C# function that runs in a worker process that is isolated from the runtime. Isolated worker process is required to support C# functions running on non-LTS versions .NET and the .NET Framework.
- C# script: used primarily when creating C# functions in the Azure portal.
Important
Support will end for the in-process model on November 10, 2026. We highly recommend that you migrate your apps to the isolated worker model for full support.
This code defines and initializes the ILogger
:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace SampleApp
{
/// <summary>
/// Samples demonstrating binding to the <see cref="ServiceBusReceivedMessage"/> type.
/// </summary>
public class ServiceBusReceivedMessageFunctions
{
//<docsnippet_servicebusmessage_createlogger>
private readonly ILogger<ServiceBusReceivedMessageFunctions> _logger;
public ServiceBusReceivedMessageFunctions(ILogger<ServiceBusReceivedMessageFunctions> logger)
{
_logger = logger;
}
//</docsnippet_servicebusmessage_createlogger>
/// <summary>
/// This function demonstrates binding to a single <see cref="ServiceBusReceivedMessage"/>.
/// </summary>
//<docsnippet_servicebus_readmessage>
[Function(nameof(ServiceBusReceivedMessageFunction))]
[ServiceBusOutput("outputQueue", Connection = "ServiceBusConnection")]
public string ServiceBusReceivedMessageFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")] ServiceBusReceivedMessage message)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
var outputMessage = $"Output message created at {DateTime.Now}";
return outputMessage;
}
//</docsnippet_servicebus_readmessage>
/// <summary>
/// This function demonstrates binding to an array of <see cref="ServiceBusReceivedMessage"/>.
/// Note that when doing so, you must also set the <see cref="ServiceBusTriggerAttribute.IsBatched"/> property
/// to <value>true</value>.
/// </summary>
//<docsnippet_servicebus_readbatch>
[Function(nameof(ServiceBusReceivedMessageBatchFunction))]
public void ServiceBusReceivedMessageBatchFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", IsBatched = true)] ServiceBusReceivedMessage[] messages)
{
foreach (ServiceBusReceivedMessage message in messages)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
}
}
//</docsnippet_servicebus_readbatch>
/// <summary>
/// This functions demonstrates that it is possible to bind to both the ServiceBusReceivedMessage and any of the supported binding contract
/// properties at the same time. If attempting this, the ServiceBusReceivedMessage must be the first parameter. There is not
/// much benefit to doing this as all of the binding contract properties are available as properties on the ServiceBusReceivedMessage.
/// </summary>
[Function(nameof(ServiceBusReceivedMessageWithStringProperties))]
public void ServiceBusReceivedMessageWithStringProperties(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")]
ServiceBusReceivedMessage message, string messageId, int deliveryCount)
{
// The MessageId property and the messageId parameter are the same.
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message ID: {id}", messageId);
// Similarly the DeliveryCount property and the deliveryCount parameter are the same.
_logger.LogInformation("Delivery Count: {count}", message.DeliveryCount);
_logger.LogInformation("Delivery Count: {count}", deliveryCount);
}
//<docsnippet_servicebus_message_actions>
[Function(nameof(ServiceBusMessageActionsFunction))]
public async Task ServiceBusMessageActionsFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", AutoCompleteMessages = false)]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
// Complete the message
await messageActions.CompleteMessageAsync(message);
}
//</docsnippet_servicebus_message_actions>
}
}
This example shows a C# function that receives a message and writes it to a second queue:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace SampleApp
{
/// <summary>
/// Samples demonstrating binding to the <see cref="ServiceBusReceivedMessage"/> type.
/// </summary>
public class ServiceBusReceivedMessageFunctions
{
//<docsnippet_servicebusmessage_createlogger>
private readonly ILogger<ServiceBusReceivedMessageFunctions> _logger;
public ServiceBusReceivedMessageFunctions(ILogger<ServiceBusReceivedMessageFunctions> logger)
{
_logger = logger;
}
//</docsnippet_servicebusmessage_createlogger>
/// <summary>
/// This function demonstrates binding to a single <see cref="ServiceBusReceivedMessage"/>.
/// </summary>
//<docsnippet_servicebus_readmessage>
[Function(nameof(ServiceBusReceivedMessageFunction))]
[ServiceBusOutput("outputQueue", Connection = "ServiceBusConnection")]
public string ServiceBusReceivedMessageFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")] ServiceBusReceivedMessage message)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
var outputMessage = $"Output message created at {DateTime.Now}";
return outputMessage;
}
//</docsnippet_servicebus_readmessage>
/// <summary>
/// This function demonstrates binding to an array of <see cref="ServiceBusReceivedMessage"/>.
/// Note that when doing so, you must also set the <see cref="ServiceBusTriggerAttribute.IsBatched"/> property
/// to <value>true</value>.
/// </summary>
//<docsnippet_servicebus_readbatch>
[Function(nameof(ServiceBusReceivedMessageBatchFunction))]
public void ServiceBusReceivedMessageBatchFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", IsBatched = true)] ServiceBusReceivedMessage[] messages)
{
foreach (ServiceBusReceivedMessage message in messages)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
}
}
//</docsnippet_servicebus_readbatch>
/// <summary>
/// This functions demonstrates that it is possible to bind to both the ServiceBusReceivedMessage and any of the supported binding contract
/// properties at the same time. If attempting this, the ServiceBusReceivedMessage must be the first parameter. There is not
/// much benefit to doing this as all of the binding contract properties are available as properties on the ServiceBusReceivedMessage.
/// </summary>
[Function(nameof(ServiceBusReceivedMessageWithStringProperties))]
public void ServiceBusReceivedMessageWithStringProperties(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection")]
ServiceBusReceivedMessage message, string messageId, int deliveryCount)
{
// The MessageId property and the messageId parameter are the same.
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message ID: {id}", messageId);
// Similarly the DeliveryCount property and the deliveryCount parameter are the same.
_logger.LogInformation("Delivery Count: {count}", message.DeliveryCount);
_logger.LogInformation("Delivery Count: {count}", deliveryCount);
}
//<docsnippet_servicebus_message_actions>
[Function(nameof(ServiceBusMessageActionsFunction))]
public async Task ServiceBusMessageActionsFunction(
[ServiceBusTrigger("queue", Connection = "ServiceBusConnection", AutoCompleteMessages = false)]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
_logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
// Complete the message
await messageActions.CompleteMessageAsync(message);
}
//</docsnippet_servicebus_message_actions>
}
}
This example uses an HTTP trigger with an OutputType
object to both send an HTTP response and write the output message.
[Function("HttpSendMsg")]
public async Task<OutputType> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req, FunctionContext context)
{
_logger.LogInformation($"C# HTTP trigger function processed a request for {context.InvocationId}.");
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync("HTTP response: Message sent");
return new OutputType()
{
OutputEvent = "MyMessage",
HttpResponse = response
};
}
This code defines the multiple output type OutputType
, which includes the Service Bus output binding definition on OutputEvent
:
public class OutputType
{
[ServiceBusOutput("TopicOrQueueName", Connection = "ServiceBusConnection")]
public string OutputEvent { get; set; }
public HttpResponseData HttpResponse { get; set; }
}
The following example shows a Java function that sends a message to a Service Bus queue myqueue
when triggered by an HTTP request.
@FunctionName("httpToServiceBusQueue")
@ServiceBusQueueOutput(name = "message", queueName = "myqueue", connection = "AzureServiceBusConnection")
public String pushToQueue(
@HttpTrigger(name = "request", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS)
final String message,
@HttpOutput(name = "response") final OutputBinding<T> result ) {
result.setValue(message + " has been sent.");
return message;
}
In the Java functions runtime library, use the @QueueOutput
annotation on function parameters whose value would be written to a Service Bus queue. The parameter type should be OutputBinding<T>
, where T
is any native Java type of a POJO.
Java functions can also write to a Service Bus topic. The following example uses the @ServiceBusTopicOutput
annotation to describe the configuration for the output binding.
@FunctionName("sbtopicsend")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
@ServiceBusTopicOutput(name = "message", topicName = "mytopicname", subscriptionName = "mysubscription", connection = "ServiceBusConnection") OutputBinding<String> message,
final ExecutionContext context) {
String name = request.getBody().orElse("Azure Functions");
message.setValue(name);
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
}
The following example shows a timer triggered TypeScript function that sends a queue message every 5 minutes.
import { app, InvocationContext, output, Timer } from '@azure/functions';
export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<string> {
const timeStamp = new Date().toISOString();
return `Message created at: ${timeStamp}`;
}
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
}),
handler: timerTrigger1,
});
To output multiple messages, return an array instead of a single object. For example:
import { app, InvocationContext, output, Timer } from '@azure/functions';
export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<string[]> {
// <displayInDocs>
const timeStamp = new Date().toISOString();
const message = `Message created at: ${timeStamp}`;
return [`1: ${message}`, `2: ${message}`];
// </displayInDocs>
}
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
}),
handler: timerTrigger1,
});
The following example shows a timer triggered JavaScript function that sends a queue message every 5 minutes.
const { app, output } = require('@azure/functions');
const serviceBusOutput = output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
});
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: serviceBusOutput,
handler: (myTimer, context) => {
const timeStamp = new Date().toISOString();
return `Message created at: ${timeStamp}`;
},
});
To output multiple messages, return an array instead of a single object. For example:
const { app, output } = require('@azure/functions');
const serviceBusOutput = output.serviceBusQueue({
queueName: 'testqueue',
connection: 'MyServiceBusConnection',
});
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
return: serviceBusOutput,
handler: (myTimer, context) => {
// <displayInDocs>
const timeStamp = new Date().toISOString();
const message = `Message created at: ${timeStamp}`;
return [`1: ${message}`, `2: ${message}`];
// </displayInDocs>
},
});
The following example shows a Service Bus output binding in a function.json file and a PowerShell function that uses the binding.
Here's the binding data in the function.json file:
{
"bindings": [
{
"type": "serviceBus",
"direction": "out",
"connection": "AzureServiceBusConnectionString",
"name": "outputSbMsg",
"queueName": "outqueue",
"topicName": "outtopic"
}
]
}
Here's the PowerShell that creates a message as the function's output.
param($QueueItem, $TriggerMetadata)
Push-OutputBinding -Name outputSbMsg -Value @{
name = $QueueItem.name
employeeId = $QueueItem.employeeId
address = $QueueItem.address
}
The following example demonstrates how to write out to a Service Bus queue in Python. The example depends on whether you use the v1 or v2 Python programming model.
import logging
import azure.functions as func
app = func.FunctionApp()
@app.route(route="put_message")
@app.service_bus_topic_output(arg_name="message",
connection="<CONNECTION_SETTING>",
topic_name="<TOPIC_NAME>")
def main(req: func.HttpRequest, message: func.Out[str]) -> func.HttpResponse:
input_msg = req.params.get('message')
message.set(input_msg)
return 'OK'
Attributes
Both in-process and isolated worker process C# libraries use attributes to define the output binding. C# script instead uses a function.json configuration file as described in the C# scripting guide.
In C# class libraries, use the ServiceBusOutputAttribute to define the queue or topic written to by the output.
The following table explains the properties you can set using the attribute:
Property | Description |
---|---|
EntityType | Sets the entity type as either Queue for sending messages to a queue or Topic when sending messages to a topic. |
QueueOrTopicName | Name of the topic or queue to send messages to. Use EntityType to set the destination type. |
Connection | The name of an app setting or setting collection that specifies how to connect to Service Bus. See Connections. |
Decorators
Applies only to the Python v2 programming model.
For Python v2 functions defined using a decorator, the following properties on the service_bus_topic_output
:
Property | Description |
---|---|
arg_name |
The name of the variable that represents the queue or topic message in function code. |
queue_name |
Name of the queue. Set only if sending queue messages, not for a topic. |
topic_name |
Name of the topic. Set only if sending topic messages, not for a queue. |
connection |
The name of an app setting or setting collection that specifies how to connect to Service Bus. See Connections. |
For Python functions defined by using function.json, see the Configuration section.
Annotations
The ServiceBusQueueOutput
and ServiceBusTopicOutput
annotations are available to write a message as a function output. The parameter decorated with these annotations must be declared as an OutputBinding<T>
where T
is the type corresponding to the message's type.
When you're developing locally, add your application settings in the local.settings.json file in the Values
collection.
Configuration
Applies only to the Python v1 programming model.
The following table explains the properties that you can set on the options
object passed to the output.serviceBusQueue()
method.
Property | Description |
---|---|
queueName | Name of the queue. |
connection | The name of an app setting or setting collection that specifies how to connect to Service Bus. See Connections. |
The following table explains the properties that you can set on the options
object passed to the output.serviceBusTopic()
method.
Property | Description |
---|---|
topicName | Name of the topic. |
connection | The name of an app setting or setting collection that specifies how to connect to Service Bus. See Connections. |
When you're developing locally, add your application settings in the local.settings.json file in the Values
collection.
The following table explains the binding configuration properties that you set in the function.json file and the ServiceBus
attribute.
function.json property | Description |
---|---|
type | Must be set to "serviceBus". This property is set automatically when you create the trigger in the Azure portal. |
direction | Must be set to "out". This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that represents the queue or topic message in function code. Set to "$return" to reference the function return value. |
queueName | Name of the queue. Set only if sending queue messages, not for a topic. |
topicName | Name of the topic. Set only if sending topic messages, not for a queue. |
connection | The name of an app setting or setting collection that specifies how to connect to Service Bus. See Connections. |
accessRights (v1 only) | Access rights for the connection string. Available values are manage and listen . The default is manage , which indicates that the connection has the Manage permission. If you use a connection string that does not have the Manage permission, set accessRights to "listen". Otherwise, the Functions runtime might fail trying to do operations that require manage rights. In Azure Functions version 2.x and higher, this property is not available because the latest version of the Service Bus SDK doesn't support manage operations. |
When you're developing locally, add your application settings in the local.settings.json file in the Values
collection.
See the Example section for complete examples.
Usage
The following output parameter types are supported by all C# modalities and extension versions:
Type | Description |
---|---|
System.String | Use when the message to write is simple text. When the parameter value is null when the function exits, Functions doesn't create a message. |
byte[] | Use for writing binary data messages. When the parameter value is null when the function exits, Functions doesn't create a message. |
Object | When a message contains JSON, Functions serializes the object into a JSON message payload. When the parameter value is null when the function exits, Functions creates a message with a null object. |
Messaging-specific parameter types contain additional message metadata. The specific types supported by the output binding depend on the Functions runtime version, the extension package version, and the C# modality used.
When you want the function to write a single message, the Service Bus output binding can bind to the following types:
Type | Description |
---|---|
string |
The message as a string. Use when the message is simple text. |
byte[] |
The bytes of the message. |
JSON serializable types | An object representing the message. Functions attempts to serialize a plain-old CLR object (POCO) type into JSON data. |
When you want the function to write multiple messages, the Service Bus output binding can bind to the following types:
Type | Description |
---|---|
T[] where T is one of the single message types |
An array containing multiple message. Each entry represents one message. |
For other output scenarios, create and use types from Azure.Messaging.ServiceBus directly.
In Azure Functions 1.x, the runtime creates the queue if it doesn't exist and you have set accessRights
to manage
. In Azure Functions version 2.x and higher, the queue or topic must already exist; if you specify a queue or topic that doesn't exist, the function fails.
Use the Azure Service Bus SDK rather than the built-in output binding.
Output to the Service Bus is available via the Push-OutputBinding
cmdlet where you pass arguments that match the name designated by binding's name parameter in the function.json file.
Use the Azure Service Bus SDK rather than the built-in output binding.
For a complete example, see the examples section.
Connections
The connection
property is a reference to environment configuration which specifies how the app should connect to Service Bus. It may specify:
- The name of an application setting containing a connection string
- The name of a shared prefix for multiple application settings, together defining an identity-based connection.
If the configured value is both an exact match for a single setting and a prefix match for other settings, the exact match is used.
Connection string
To obtain a connection string, follow the steps shown at Get the management credentials. The connection string must be for a Service Bus namespace, not limited to a specific queue or topic.
This connection string should be stored in an application setting with a name matching the value specified by the connection
property of the binding configuration.
If the app setting name begins with "AzureWebJobs", you can specify only the remainder of the name. For example, if you set connection
to "MyServiceBus", the Functions runtime looks for an app setting that is named "AzureWebJobsMyServiceBus". If you leave connection
empty, the Functions runtime uses the default Service Bus connection string in the app setting that is named "AzureWebJobsServiceBus".
Identity-based connections
If you are using version 5.x or higher of the extension, instead of using a connection string with a secret, you can have the app use an Azure Active Directory identity. To do this, you would define settings under a common prefix which maps to the connection
property in the trigger and binding configuration.
In this mode, the extension requires the following properties:
Property | Environment variable template | Description | Example value |
---|---|---|---|
Fully Qualified Namespace | <CONNECTION_NAME_PREFIX>__fullyQualifiedNamespace |
The fully qualified Service Bus namespace. | <service_bus_namespace>.servicebus.chinacloudapi.cn |
Additional properties may be set to customize the connection. See Common properties for identity-based connections.
Note
When using Azure App Configuration or Key Vault to provide settings for Managed Identity connections, setting names should use a valid key separator such as :
or /
in place of the __
to ensure names are resolved correctly.
For example, <CONNECTION_NAME_PREFIX>:fullyQualifiedNamespace
.
When hosted in the Azure Functions service, identity-based connections use a managed identity. The system-assigned identity is used by default, although a user-assigned identity can be specified with the credential
and clientID
properties. Note that configuring a user-assigned identity with a resource ID is not supported. When run in other contexts, such as local development, your developer identity is used instead, although this can be customized. See Local development with identity-based connections.
Grant permission to the identity
Whatever identity is being used must have permissions to perform the intended actions. For most Azure services, this means you need to assign a role in Azure RBAC, using either built-in or custom roles which provide those permissions.
Important
Some permissions might be exposed by the target service that are not necessary for all contexts. Where possible, adhere to the principle of least privilege, granting the identity only required privileges. For example, if the app only needs to be able to read from a data source, use a role that only has permission to read. It would be inappropriate to assign a role that also allows writing to that service, as this would be excessive permission for a read operation. Similarly, you would want to ensure the role assignment is scoped only over the resources that need to be read.
You'll need to create a role assignment that provides access to your topics and queues at runtime. Management roles like Owner aren't sufficient. The following table shows built-in roles that are recommended when using the Service Bus extension in normal operation. Your application may require additional permissions based on the code you write.
Binding type | Example built-in roles |
---|---|
Trigger1 | Azure Service Bus Data Receiver, Azure Service Bus Data Owner |
Output binding | Azure Service Bus Data Sender |
1 For triggering from Service Bus topics, the role assignment needs to have effective scope over the Service Bus subscription resource. If only the topic is included, an error will occur. Some clients, such as the Azure portal, don't expose the Service Bus subscription resource as a scope for role assignment. In such cases, the Azure CLI may be used instead. To learn more, see Azure built-in roles for Azure Service Bus.
Exceptions and return codes
Binding | Reference |
---|---|
Service Bus | Service Bus Error Codes |
Service Bus | Service Bus Limits |