Azure 事件方格 output binding for Azure Functions

使用事件方格輸出系結,將事件寫入自定義主題。 你必須擁有該 自訂主題的有效存取金鑰。 事件方格輸出系結不支援共用存取簽章 (SAS) 令牌。

關於設定與設定細節,請參見 如何在 Azure Functions 中使用事件格觸發器與綁定。

重要

本文使用索引標籤來支援多個版本的 Node.js 程式設計模型。 v4 模型已正式推出,旨在為 JavaScript 和 TypeScript 開發人員提供更靈活且更直覺的體驗。 關於 v4 模型的更多運作細節,請參閱 Azure Functions Node.js 開發者指南。 若要深入了解 v3 與 v4 之間的差異,請參閱移轉指南。

Azure Functions 支援兩種 Python 程式設計模型。 您定義系結的方式取決於您所選擇的程式設計模型。

Python v2 程式設計模型允許你直接在 Python 函式程式碼中使用裝飾器來定義綁定。 更多資訊請參閱 Python 開發者指南。

本文支援這兩種程序設計模型。

範例

目前這款綁定沒有 Go 支援。

事件網格輸出綁定所使用的輸出參數類型取決於綁定擴充版本及 C# 函式的模態。 C# 函式可以使用下列其中一種 C# 模式來建立:

下列範例示範如何在觸發程式和事件方格輸出系結中使用自訂類型:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace SampleApp
{
    public static class EventGridFunction
    {
        [Function(nameof(EventGridFunction))]
        [EventGridOutput(TopicEndpointUri = "MyEventGridTopicUriSetting", TopicKeySetting = "MyEventGridTopicKeySetting")]
        public static MyEventType Run([EventGridTrigger] MyEventType input, FunctionContext context)
        {
            var logger = context.GetLogger(nameof(EventGridFunction));
            logger.LogInformation(input.Data?.ToString());

            var outputEvent = new MyEventType()
            {
                Id = "unique-id",
                Subject = "abc-subject",
                Data = new Dictionary<string, object>
                {
                    { "myKey", "myValue" }
                }
            };

            return outputEvent;
        }
    }

    public class MyEventType
    {
        public string? Id { get; set; }

        public string? Topic { get; set; }

        public string? Subject { get; set; }

        public string? EventType { get; set; }

        public DateTime EventTime { get; set; }

        public IDictionary<string, object>? Data { get; set; }
    }
}

以下範例展示了一個 Java 函式,該函式會將訊息寫入事件網格的自訂主題。 這個函式會使用綁定的方法 setValue 來輸出字串。

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<String> outputEvent,
            final ExecutionContext context) {
        context.getLogger().info("Java EventGrid trigger processed a request." + content);
        final String eventGridOutputDocument = "{\"id\": \"1807\", \"eventType\": \"recordInserted\", \"subject\": \"myapp/cars/java\", \"eventTime\":\"2017-08-10T21:03:07+00:00\", \"data\": {\"make\": \"Ducati\",\"model\": \"Monster\"}, \"dataVersion\": \"1.0\"}";
        outputEvent.setValue(eventGridOutputDocument);
    }
}

您也可以使用 POJO 類別來傳送事件方格訊息。

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<EventGridEvent> outputEvent,
            final ExecutionContext context) {
        context.getLogger().info("Java EventGrid trigger processed a request." + content);

        final EventGridEvent eventGridOutputDocument = new EventGridEvent();
        eventGridOutputDocument.setId("1807");
        eventGridOutputDocument.setEventType("recordInserted");
        eventGridOutputDocument.setEventTime("2017-08-10T21:03:07+00:00");
        eventGridOutputDocument.setDataVersion("1.0");
        eventGridOutputDocument.setSubject("myapp/cars/java");
        eventGridOutputDocument.setData("{\"make\": \"Ducati\",\"model\":\"monster\"");

        outputEvent.setValue(eventGridOutputDocument);
    }
}

class EventGridEvent {
    private String id;
    private String eventType;
    private String subject;
    private String eventTime;
    private String dataVersion;
    private String data;

    public String getId() {
        return id;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getDataVersion() {
        return dataVersion;
    }

    public void setDataVersion(String dataVersion) {
        this.dataVersion = dataVersion;
    }

    public String getEventTime() {
        return eventTime;
    }

    public void setEventTime(String eventTime) {
        this.eventTime = eventTime;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getEventType() {
        return eventType;
    }

    public void setEventType(String eventType) {
        this.eventType = eventType;
    }

    public void setId(String id) {
        this.id = id;
    }  
}

以下範例展示了一個計時器觸發的 TypeScript 函式 ,該函式會輸出單一事件:

import { app, EventGridPartialEvent, InvocationContext, output, Timer } from '@azure/functions';

export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<EventGridPartialEvent> {
    const timeStamp = new Date().toISOString();
    return {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    };
}

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: output.eventGrid({
        topicEndpointUri: 'MyEventGridTopicUriSetting',
        topicKeySetting: 'MyEventGridTopicKeySetting',
    }),
    handler: timerTrigger1,
});

若要輸出多個事件,請傳回數位,而不是單一物件。 例如:

const timeStamp = new Date().toISOString();
return [
    {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    },
    {
        id: 'message-id-2',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Doe',
        },
        eventTime: timeStamp,
    },
];

以下範例展示了一個計時器觸發的 JavaScript 函式 ,該函式輸出單一事件:

const { app, output } = require('@azure/functions');

const eventGridOutput = output.eventGrid({
    topicEndpointUri: 'MyEventGridTopicUriSetting',
    topicKeySetting: 'MyEventGridTopicKeySetting',
});

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: eventGridOutput,
    handler: (myTimer, context) => {
        const timeStamp = new Date().toISOString();
        return {
            id: 'message-id',
            subject: 'subject-name',
            dataVersion: '1.0',
            eventType: 'event-type',
            data: {
                name: 'John Henry',
            },
            eventTime: timeStamp,
        };
    },
});

若要輸出多個事件,請傳回數位,而不是單一物件。 例如:

const timeStamp = new Date().toISOString();
return [
    {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    },
    {
        id: 'message-id-2',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Doe',
        },
        eventTime: timeStamp,
    },
];

下列範例示範如何設定函式以輸出事件方格事件訊息。 其中的部分 type 設定用 eventGrid 來設定建立事件網格輸出綁定所需的值。

{
  "bindings": [
    {
      "type": "eventGrid",
      "name": "outputEvent",
      "topicEndpointUri": "MyEventGridTopicUriSetting",
      "topicKeySetting": "MyEventGridTopicKeySetting",
      "direction": "out"
    },
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}

在你的函式中,使用 透過 Push-OutputBinding 事件網格輸出綁定將事件傳送到自訂主題。

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$message = $Request.Query.Message

Push-OutputBinding -Name outputEvent -Value  @{
    id = "1"
    eventType = "testEvent"
    subject = "testapp/testPublish"
    eventTime = "2020-08-27T21:03:07+00:00"
    data = @{
        Message = $message
    }
    dataVersion = "1.0"
}

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = 200
    Body = "OK"
})

以下範例展示了觸發綁定以及使用該綁定的 Python 函式。 接著會依照 topicEndpointUri. 這個範例取決於你使用的是 v1 還是 v2 Python程式模型。

以下是 function_app.py 檔案中的 函式:

import logging
import azure.functions as func
import datetime

app = func.FunctionApp()

@app.function_name(name="eventgrid_output")
@app.event_grid_trigger(arg_name="eventGridEvent")
@app.event_grid_output(
    arg_name="outputEvent",
    topic_endpoint_uri="MyEventGridTopicUriSetting",
    topic_key_setting="MyEventGridTopicKeySetting")
def eventgrid_output(eventGridEvent: func.EventGridEvent, 
         outputEvent: func.Out[func.EventGridOutputEvent]) -> None:

    logging.log("eventGridEvent: ", eventGridEvent)

    outputEvent.set(
        func.EventGridOutputEvent(
            id="test-id",
            data={"tag1": "value1", "tag2": "value2"},
            subject="test-subject",
            event_type="test-event-1",
            event_time=datetime.datetime.utcnow(),
            data_version="1.0"))

屬性

進程內和隔離的背景工作進程 C# 連結庫都會使用 屬性來設定系結。 C# 文稿會改用function.json組態檔,如 C# 腳本指南中所述。

屬性的建構函式會採用包含自定義主題名稱的應用程式設定名稱,以及包含主題索引鍵的應用程式設定名稱。

下表說明了 的 EventGridOutputAttribute參數。

參數 描述
TopicEndpointUri 應用程式設定的名稱,其中包含自訂主題的 URI,例如 MyTopicEndpointUri。
主題鍵設定 應用程式設定的名稱,其中包含自訂主題的存取金鑰。
連接* 包含主題端點 URI 之設定的通用前置詞值。 關於此應用設定的命名格式,請參見 基於身份的驗證。

註釋

對於Java類別,請使用 EventGridAttribute 屬性。

屬性的建構函式會採用包含自定義主題名稱的應用程式設定名稱,以及包含主題索引鍵的應用程式設定名稱。 欲了解更多設定資訊,請參閱 輸出 - 設定。 這裡有一個 EventGridOutput 屬性範例:

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<String> outputEvent, final ExecutionContext context) {
            ...
    }
}

組態

下表說明您可以在傳遞至 options 方法的物件output.eventGrid()上設定的屬性。

屬性 描述
topicEndpointUri 應用程式設定的名稱,其中包含自訂主題的 URI,例如 MyTopicEndpointUri。
topicKeySetting 應用程式設定的名稱,其中包含自訂主題的存取金鑰。
連接* 包含主題端點 URI 之設定的通用前置詞值。 設定屬性時connection,topicEndpointUritopicKeySetting和屬性不應該被設定。 關於此應用設定的命名格式,請參見 基於身份的驗證。

組態

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必須設定為 eventGrid。
方向 必須設定為 out。 這個參數會在你在 Azure 入口網站建立綁定時自動設定。
name 函式程式碼中所使用的變數名稱,代表事件。
topicEndpointUri 應用程式設定的名稱,其中包含自訂主題的 URI,例如 MyTopicEndpointUri。
topicKeySetting 應用程式設定的名稱,其中包含自訂主題的存取金鑰。
連接* 包含主題端點 URI 之設定的通用前置詞值。 關於此應用設定的命名格式,請參見 基於身份的驗證。

*支援基於身份的連線需要擴充功能版本 3.3.x 或更高版本。

當您在本機開發時,請在集合中的 local.settings.json 檔案Values中新增應用程式設定。

重要

確保你把 的 TopicEndpointUri 值設為包含自訂主題 URI 的應用程式設定名稱。 請勿直接在此屬性中指定自定義主題的 URI。 使用 Connection時也是一樣。

如需完整範例,請參閱範例一節。

使用方式

事件網格輸出綁定所支援的參數類型取決於擴充套件版本及所使用的 C# 模態。

當您想要讓函式撰寫單一事件時,Event Grid 輸出系結可以繫結至下列類型:

類型 描述
string 事件做為字串。
byte[] 事件訊息的位元組。
JSON 可序列化型別 物件,表示 JSON 事件。 函式會嘗試將一般舊的CLR物件 (POCO) 類型串行化為 JSON 數據。

當您想要函式寫入多個事件時,Event Grid 輸出系結可以繫結至下列類型:

類型 描述
T[] 其中 T 是其中一個單一事件類型 包含多個事件的陣列。 每個專案都代表一個事件。

對於其他輸出情境,則建立並使用 EventGridPublisherClient,搭配 Azure 的其他類型。直接 Messageaging.EventGrid。 請參見 Register Azure clients,了解如何利用依賴注入從 Azure SDK 建立客戶端類型。

透過呼叫方法參數(如 out EventGridOutput paramName,)發送個別訊息,並寫入多個訊息。ICollector<EventGridOutput>

直接或使用 context.extraOutputs.set()傳回 值,以存取輸出訊息。

透過 cmdlet Push-OutputBinding 將事件傳送到事件網格的輸出綁定,來存取輸出事件。

有兩個選項可從函式輸出事件方格訊息:

  • 傳回值:將 name 中的。 使用此組態時,函式的傳回值會保存為事件方格訊息。
  • 命令式:將值傳遞至宣告為 Out 類型的參數的 set 方法。 傳遞給 set 的值會以事件網格訊息的形式持續存在。

輸出函數參數必須定義為 func.Out[str]、 func.Out[bytes]、 func.Out[func.EventGridOutputEvent]、 或 func.Out[List[func.EventGridOutputEvent]]。 如需詳細資訊,請參閱 輸出範例 。

連線

使用事件方格輸出系結時,有兩種方式可以向事件方格主題進行驗證:

驗證方法 描述
使用主題索引鍵 請依照 TopicEndpointUri項描述設定 TopicKeySetting 和 屬性。
使用身分識別 將屬性設定 Connection 為多個應用程式設定的共用前綴名稱,並共同定義 基於身份的驗證。 使用 3.3.x 版或更新版本的擴充功能時,支援此方法。

使用主題金鑰

使用下列步驟來設定主題金鑰:

  1. 請依照 「取得存取金鑰 」中的步驟,取得你事件網格主題的主題金鑰。

  2. 在您的應用程式設定中,建立定義主題索引鍵值的設定。 使用這個設定的名稱作為 TopicKeySetting 綁定的屬性。

  3. 在您的應用程式設定中,建立定義主題端點的設定。 使用這個設定的名稱作為 TopicEndpointUri 綁定的屬性。

以身分識別為基礎的驗證

使用擴充功能 3.3.x 或更高版本時,你可以使用 Microsoft Entra身份碼連接事件網格主題,避免取得和操作主題鍵。

您必須建立會傳回主題端點 URI 的應用程式設定。 設定名稱應結合 唯一共用前綴 (例如 myawesometopic)與值 __topicEndpointUri。 接著,在定義myawesometopic綁定屬性時,必須使用該常見前綴(此例Connection為 )。

在此模式中,延伸模組需要下列屬性:

屬性 環境變數範本 描述 範例值
主題端點 URI <CONNECTION_NAME_PREFIX>__topicEndpointUri 主題端點。 https://<topic-name>.centralus-1.eventgrid.azure.net/api/events

您可以使用更多屬性來自定義連線。 請參閱身分識別型連線的通用屬性。

注意

當使用 Azure 應用程式組態 或 金鑰保存庫 來設定基於受管理身份的連線時,設定名稱應使用有效的金鑰分隔符,如 或 ,以取代 ,以確保名稱正確解析。

例如: <CONNECTION_NAME_PREFIX>:topicEndpointUri 。

當 Azure Functions 服務中託管時,基於身份的連線使用 managed identity。 雖然可以使用 credential 和 clientID 屬性指定使用者指派的身分識別,但預設會使用系統指派的身分識別。 請注意,不支援以資源識別碼來設定使用者指派的身分識別。 在本機開發等其他內容中執行時,雖然這可以自訂,但仍會改用您的開發人員身分識別。 請參閱使用身分識別型連線進行本機開發。

授與權限給身分識別

正在使用的任何身分識別,都必須具有執行預期動作的權限。 對大多數Azure服務而言,這表示你需要在 Azure RBAC 中指派角色,使用內建或自訂的角色來提供這些權限。

重要

部分權限可能會由所有內容都不需要的目標服務公開。 可以的話,請遵循最低權限原則,只授與身分識別所需的權限。 例如,如果應用程式只需要能夠讀取資料來源,請使用只有讀取權限的角色。 不宜指派也允許寫入該服務的角色,因為讀取作業不需要這麼多權限。 同樣地,最好確保角色指派的範圍僅限於需要讀取的資源。

您必須建立可在執行階段存取事件方格主題的角色指派。 擁有者等的管理角色不足。 下方資料表顯示一般作業中使用事件中樞延伸模組時建議的內建角色。 您的應用程式可能會根據您寫入的程式碼要求額外的權限。

繫結類型 內建角色範例
輸出繫結 EventGrid 參與者、EventGrid 資料傳送者

下一步