Azure Functions Input Bindings: Event Hubs

Introduction to Event Hubs Input Bindings

Azure Event Hubs is a highly scalable data streaming platform and event ingestion service. Azure Functions can integrate with Event Hubs using input bindings to easily consume events from an Event Hub. This allows your functions to react to incoming data streams without managing low-level client code.

Input bindings enable your function to read data from an Event Hub as a trigger or as a parameter to your function. This documentation focuses on using Event Hubs as an input binding to retrieve messages.

How Event Hubs Input Bindings Work

When configured as an input binding, Azure Functions automatically reads messages from a specified Event Hub partition. The binding can be configured to receive a single message, a batch of messages, or even specific properties of the Event Hub message.

The runtime handles checkpointing for you, ensuring that messages are processed reliably. You typically don't need to worry about offset management when using the input binding.

Configuration

The Event Hubs input binding is configured in your function.json file. Here's a typical configuration for an input binding:

{
  "bindings": [
    {
      "type": "eventHubTrigger",
      "name": "messages",
      "direction": "in",
      "eventHubName": "my-event-hub",
      "connection": "EventHubConnectionAppSetting"
    }
    // ... other bindings
  ]
}

Properties:

Property Description Required
type Must be eventHubTrigger for input bindings. Yes
name The name of the parameter in your function code that will receive the messages. Yes
direction Must be in. Yes
eventHubName The name of the Event Hub to read from. Yes
connection The name of an app setting that contains the Event Hub connection string. Yes
consumerGroup (Optional) The consumer group to use. Defaults to $Default. No
cardinality (Optional) Specifies whether to receive a single message or a batch. Possible values: one (default, single message) or many (array of messages). No
accessRights (Optional) The access rights for the binding. For input, this is implicitly Listen. No

The connection property refers to an application setting in your Azure Functions configuration, typically containing a connection string like: Endpoint=sb://your-event-hubs-namespace.servicebus.windows.net/;SharedAccessKeyName=your-key-name;SharedAccessKey=your-key-value

Function Code Examples

The name property in function.json maps to the parameter name in your function.

C# Example (Single Message)

When cardinality is not specified or is one, you receive a single event.

using Microsoft.Azure.EventHubs;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

public static class EventHubInputFunction
{
    [FunctionName("ProcessEventHubMessage")]
    public static void Run(
        [EventHubTrigger("my-event-hub", Connection = "EventHubConnectionAppSetting")] EventData message,
        ILogger log)
    {
        log.LogInformation($"C# Event Hub trigger function processed a message: {message.SystemProperties.SequenceNumber}");
        log.LogInformation($"Message body: {System.Text.Encoding.UTF8.GetString(message.Body)}");
    }
}

C# Example (Batch of Messages)

To receive a batch of messages, set cardinality to many in function.json.

using Microsoft.Azure.EventHubs;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;

public static class EventHubBatchInputFunction
{
    [FunctionName("ProcessEventHubMessages")]
    public static void Run(
        [EventHubTrigger("my-event-hub", Connection = "EventHubConnectionAppSetting", Cardinality = Cardinality.Many)] EventData[] messages,
        ILogger log)
    {
        log.LogInformation($"C# Event Hub trigger function processed a batch of {messages.Length} messages.");

        foreach (var message in messages)
        {
            log.LogInformation($"Message SequenceNumber: {message.SystemProperties.SequenceNumber}");
            log.LogInformation($"Message body: {System.Text.Encoding.UTF8.GetString(message.Body)}");
        }
    }
}

Node.js Example (Batch of Messages)

In Node.js, a batch is represented as an array.

module.exports = async function (context, messages) {
    context.log(`JavaScript event hub trigger function processed a batch of ${messages.length} messages.`);

    for (let i = 0; i < messages.length; i++) {
        const message = messages[i];
        context.log(`Processing message: ${message.sequenceNumber}`);
        context.log(`Message body: ${message.body}`);
    }
};

And the corresponding function.json for Node.js (assuming batch):

{
  "bindings": [
    {
      "type": "eventHubTrigger",
      "name": "messages",
      "direction": "in",
      "eventHubName": "my-event-hub",
      "connection": "EventHubConnectionAppSetting",
      "cardinality": "many"
    }
  ]
}

EventData Object

The EventData object (or its equivalent in other languages) provides access to the message content and metadata. Key properties include:

Note: When using the many cardinality, the runtime attempts to batch events from the same partition. The size of the batch can be influenced by triggers and other runtime configurations.

Error Handling and Retries

Azure Functions runtime has built-in retry mechanisms for Event Hubs triggers. If your function fails to process a message (or batch), the runtime will attempt to redeliver it. For persistent failures, consider implementing dead-lettering mechanisms by sending problematic messages to a separate queue or storage.

Warning: Be mindful of idempotency in your function logic, as messages might be reprocessed during retries.

Advanced Scenarios