適用於 Azure Functions 的 Azure 事件方格輸出繫結

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

如需安裝和組態詳細數據的詳細資訊,請參閱 如何在 Azure Functions 中使用事件方格觸發程式和系結。

重要

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

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

Python v2 程式設計模型可讓您直接在 Python 函式程式代碼中使用裝飾項目來定義系結。 如需詳細資訊,請參閱 Python 開發人員指南

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

重要

Event Grid 輸出系結僅適用於 Functions 2.x 和更新版本。

範例

搭配 Event Grid 輸出系結使用的輸出參數類型取決於 Functions 運行時間版本、系結延伸模組版本,以及 C# 函式的形式。 C# 函式可以使用下列其中一種 C# 模式來建立:

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

using System;
using System.Collections.Generic;
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,
    },
];

下列範例示範如何設定函式以輸出事件方格事件訊息。 設定 為 的區段 typeeventGrid 設定建立事件方格輸出系結所需的值。

{
  "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
TopicKeySetting 應用程式設定的名稱,其中包含自訂主題的存取金鑰。
connection* 包含主題端點 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) {
            ...
    }
}

組態

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

屬性 說明
topicEndpointUri 應用程式設定的名稱,其中包含自訂主題的 URI,例如 MyTopicEndpointUri
topicKeySetting 應用程式設定的名稱,其中包含自訂主題的存取金鑰。
connection* 包含主題端點 URI 之設定的通用前置詞值。 設定 connection 屬性時, topicEndpointUri 不應該設定 和 topicKeySetting 屬性。 如需此應用程式設定命名格式的詳細資訊,請參閱 以身分識別為基礎的驗證

組態

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

function.json 屬性 描述
type 必須設定為 eventGrid
direction 必須設定為 out。 當您在 Azure 入口網站中建立繫結時,會自動設定此參數。
name 函式程式碼中所使用的變數名稱,代表事件。
topicEndpointUri 應用程式設定的名稱,其中包含自訂主題的 URI,例如 MyTopicEndpointUri
topicKeySetting 應用程式設定的名稱,其中包含自訂主題的存取金鑰。
connection* 包含主題端點 URI 之設定的通用前置詞值。 如需此應用程式設定命名格式的詳細資訊,請參閱 以身分識別為基礎的驗證

*支援身分識別型連線需要 3.3.x 版或更新版本的擴充功能。

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

重要

請確定您已將的值 TopicEndpointUri 設定為包含自訂主題 URI 的應用程式設定名稱。 請勿直接在此屬性中指定自定義主題的 URI。 使用 Connection時,同樣適用。

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

使用方式

事件方格輸出系結所支援的參數類型取決於 Functions 運行時間版本、擴充套件版本,以及所使用的 C# 形式。

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

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

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

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

針對其他輸出案例,請直接從 Azure.Messaging.EventGrid 建立和使用類型。

藉由呼叫 方法參數來傳送個別訊息,例如 out EventGridOutput paramName,並使用 撰寫多個訊息 ICollector<EventGridOutput>

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

使用 Push-OutputBinding Cmdlet 將事件傳送至事件方格輸出系結,以存取輸出事件。

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

  • 傳回值:將 name 中的屬性設定為 $returnfunction.json。 使用此組態時,函式的傳回值會保存為事件方格訊息。
  • 命令式:將值傳遞至宣告為 Out 類型的參數的 set 方法。 傳遞至 set 的值會保存為事件方格訊息。

連線

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

驗證方法 描述
使用主題索引鍵 TopicEndpointUri設定 和 TopicKeySetting 屬性,如使用主題索引鍵中所述
使用身分識別 Connection 屬性設定為多個應用程式設定的共用前置詞名稱,並定義 以身分識別為基礎的驗證。 使用 3.3.x 版或更新版本的擴充功能時,支援此方法。

使用主題金鑰

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

  1. 請遵循取得存取金鑰中的步驟,取得事件方格主題的主題密鑰。

  2. 在您的應用程式設定中,建立定義主題索引鍵值的設定。 針對系結的 屬性,請使用此設定 TopicKeySetting 的名稱。

  3. 在您的應用程式設定中,建立定義主題端點的設定。 針對系結的 屬性,請使用此設定 TopicEndpointUri 的名稱。

以身分識別為基礎的驗證

使用 3.3.x 版或更新版本的擴充功能時,您可以使用 Microsoft Entra 身分識別連線到事件方格主題,以避免必須取得和使用主題密鑰。

您必須建立會傳回主題端點 URI 的應用程式設定。 設定的名稱應該結合唯一 的通用前置詞 (例如 myawesometopic, ) 與 值 __topicEndpointUri。 然後,當您在系結中定義 Connection 屬性時,myawesometopic必須使用該通用前置詞(在此案例中為 )。

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

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

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

注意

使用 Azure 應用程式組態金鑰保存庫 來提供受控識別型連線的設定時,設定名稱應該使用有效的索引鍵分隔符,例如 :/ 取代 __ ,以確保正確解析名稱。

例如: <CONNECTION_NAME_PREFIX>:topicEndpointUri

主控於 Azure Functions 服務時,以身分識別為基礎的連接會使用受控識別。 雖然可以使用 credentialclientID 屬性指定使用者指派的身分識別,但預設會使用系統指派的身分識別。 請注意,不支援使用資源標識符設定使用者指派的身分識別。 在其他內容中執行時,例如本機開發,會改用您的開發人員身分識別,但您可以自定義此身分識別。 請參閱 使用身分識別型連線進行本機開發。

授與權限給身分識別

正在使用的任何身分識別,都必須具有執行預期動作的權限。 對於大部分的 Azure 服務,這表示您必須 使用內建或自定義角色,在 Azure RBAC 中指派角色,以提供這些許可權。

重要

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

您必須建立角色指派,以在運行時間存取事件方格主題。 擁有者之類的管理角色不足。 下表顯示正常作業中使用事件中樞擴充功能時建議的內建角色。 您的應用程式可能需要根據您撰寫的程式代碼來取得其他許可權。

繫結類型 範例內建角色
輸出繫結 EventGrid 參與者EventGrid 數據傳送者

下一步