Community라이팅 & 에디팅github.com

microsoft/azure-eventgrid-dotnet

Azure Event Grid SDK for .NET. Azure Event Grid를 사용하여 이벤트를 게시 및 소비하기 위한 클라이언트 라이브러리입니다. 이벤트 기반 아키텍처, pub/sub 메시징, CloudEvents 및 EventGridEvents에 사용됩니다. 트리거: "Event Grid", "EventGridPublisherClient", "CloudEvent", "EventGridEvent", "publish events .NET", "event-driven", "pub/sub".

azure-eventgrid-dotnet란 무엇인가요?

이 스킬은 .NET 애플리케이션에서 Azure Event Grid와 상호 작용하는 방법을 설명합니다. Azure.Messaging.EventGrid 클라이언트 라이브러리를 사용하여 Event Grid 주제, 도메인 및 네임스페이스에 이벤트를 게시하고, 이벤트를 수신 및 처리하는 방법을 다룹니다. 주요 기능으로는 API 키, Microsoft Entra ID, SAS 토큰을 사용한 인증, EventGridEvent 및 CloudEvent 스키마를 사용한 이벤트 게시, 풀 전송(Pull Delivery)을 통한 이벤트 수신 및 확인(acknowledge)/릴리스(release)/거부(reject) 처리, Azure Functions 트리거를 통한 이벤트 소비, 그리고 다양한 시스템 이벤트 파싱 방법을 포함합니다. 이 스킬은 Claude Code, Cursor, Codex와 같은 AI 코딩 에이전트에서 사용할 수 있으며, 개발자가 이벤트 기반 아키텍처를 구축하고 Azure Event Grid를 효과적으로 활용할 수 있도록 지원합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/microsoft/agent-skills/tree/main/.github/plugins/azure-sdk-dotnet/skills/azure-eventgrid-dotnet

Installed? Explore more 라이팅 & 에디팅 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Azure.Messaging.EventGrid (.NET)

Azure Event Grid 주제, 도메인 및 네임스페이스에 이벤트를 게시하기 위한 클라이언트 라이브러리입니다.

설치

# 주제 및 도메인 (푸시 전송)
dotnet add package Azure.Messaging.EventGrid

# 네임스페이스 (풀 전송)
dotnet add package Azure.Messaging.EventGrid.Namespaces

# CloudNative CloudEvents 상호 운용
dotnet add package Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents

현재 버전: 4.28.0 (안정화)

환경 변수

EVENT_GRID_TOPIC_ENDPOINT=https://<topic-name>.<region>.eventgrid.azure.net/api/events  # 필수: Event Grid 주제 또는 도메인 엔드포인트
EVENT_GRID_TOPIC_KEY=<access-key>  # AzureKeyCredential 인증에만 필요
EVENT_GRID_NAMESPACE_ENDPOINT=https://<namespace>.<region>.eventgrid.azure.net  # 선택 사항: Event Grid 네임스페이스 엔드포인트
EVENT_GRID_TOPIC_NAME=<topic-name>  # 필수: Event Grid 주제 이름
EVENT_GRID_SUBSCRIPTION_NAME=<subscription-name>  # 선택 사항: Event Grid 구독 이름
AZURE_TOKEN_CREDENTIALS=prod  # 프로덕션에서 DefaultAzureCredential을 사용하는 경우에만 필요

클라이언트 계층 구조

푸시 전송 (주제/도메인)
└── EventGridPublisherClient
    ├── SendEventAsync(EventGridEvent)
    ├── SendEventsAsync(IEnumerable<EventGridEvent>)
    ├── SendEventAsync(CloudEvent)
    └── SendEventsAsync(IEnumerable<CloudEvent>)

풀 전송 (네임스페이스)
├── EventGridSenderClient
│   └── SendAsync(CloudEvent)
└── EventGridReceiverClient
    ├── ReceiveAsync()
    ├── AcknowledgeAsync()
    ├── ReleaseAsync()
    └── RejectAsync()

인증

API 키 인증

using Azure;
using Azure.Messaging.EventGrid;

EventGridPublisherClient client = new(
    new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
    new AzureKeyCredential("<access-key>"));

Microsoft Entra 토큰 자격 증명

using Azure.Identity;
using Azure.Messaging.EventGrid;

// 로컬 개발: DefaultAzureCredential. 프로덕션: AZURE_TOKEN_CREDENTIALS=prod 또는 AZURE_TOKEN_CREDENTIALS=<specific_credential> 설정
var credential = new DefaultAzureCredential(
    DefaultAzureCredential.DefaultEnvironmentVariableName
);
// 또는 프로덕션에서 특정 자격 증명을 직접 사용할 수 있습니다:
// https://learn.microsoft.com/dotnet/api/overview/azure/identity-readme?view=azure-dotnet#credential-classes 참조
// var credential = new ManagedIdentityCredential();
EventGridPublisherClient client = new(
    new Uri("https://mytopic.eastus-1.eventgrid.azure.net/api/events"),
    credential);

SAS 토큰 인증

string sasToken = EventGridPublisherClient.BuildSharedAccessSignature(
    new Uri(topicEndpoint),
    DateTimeOffset.UtcNow.AddHours(1),
    new AzureKeyCredential(topicKey));

var sasCredential = new AzureSasCredential(sasToken);
EventGridPublisherClient client = new(
    new Uri(topicEndpoint),
    sasCredential);

이벤트 게시

EventGridEvent 스키마

EventGridPublisherClient client = new(
    new Uri(topicEndpoint),
    new AzureKeyCredential(topicKey));

// 단일 이벤트
EventGridEvent egEvent = new(
    subject: "orders/12345",
    eventType: "Order.Created",
    dataVersion: "1.0",
    data: new { OrderId = "12345", Amount = 99.99 });

await client.SendEventAsync(egEvent);

// 이벤트 배치
List<EventGridEvent> events = new()
{
    new EventGridEvent(
        subject: "orders/12345",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new OrderData { OrderId = "12345", Amount = 99.99 }),
    new EventGridEvent(
        subject: "orders/12346",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new OrderData { OrderId = "12346", Amount = 149.99 })
};

await client.SendEventsAsync(events);

CloudEvent 스키마

CloudEvent cloudEvent = new(
    source: "/orders/system",
    type: "Order.Created",
    data: new { OrderId = "12345", Amount = 99.99 });

cloudEvent.Subject = "orders/12345";
cloudEvent.Id = Guid.NewGuid().ToString();
cloudEvent.Time = DateTimeOffset.UtcNow;

await client.SendEventAsync(cloudEvent);

// CloudEvents 배치
List<CloudEvent> cloudEvents = new()
{
    new CloudEvent("/orders", "Order.Created", new { OrderId = "1" }),
    new CloudEvent("/orders", "Order.Updated", new { OrderId = "2" })
};

await client.SendEventsAsync(cloudEvents);

Event Grid 도메인에 게시

// 이벤트는 도메인 라우팅을 위해 Topic 속성을 지정해야 합니다.
List<EventGridEvent> events = new()
{
    new EventGridEvent(
        subject: "orders/12345",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new { OrderId = "12345" })
    {
        Topic = "orders-topic"  // 도메인 주제 이름
    },
    new EventGridEvent(
        subject: "inventory/item-1",
        eventType: "Inventory.Updated",
        dataVersion: "1.0",
        data: new { ItemId = "item-1" })
    {
        Topic = "inventory-topic"
    }
};

await client.SendEventsAsync(events);

사용자 지정 직렬화

using System.Text.Json;

var serializerOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

var customSerializer = new JsonObjectSerializer(serializerOptions);

EventGridEvent egEvent = new(
    subject: "orders/12345",
    eventType: "Order.Created",
    dataVersion: "1.0",
    data: customSerializer.Serialize(new OrderData { OrderId = "12345" }));

await client.SendEventAsync(egEvent);

풀 전송 (네임스페이스)

네임스페이스 주제로 이벤트 전송

using Azure;
using Azure.Messaging;
using Azure.Messaging.EventGrid.Namespaces;

var senderClient = new EventGridSenderClient(
    new Uri(namespaceEndpoint),
    topicName,
    new AzureKeyCredential(topicKey));

// 단일 이벤트 전송
CloudEvent cloudEvent = new("employee_source", "Employee.Created", 
    new { Name = "John", Age = 30 });
await senderClient.SendAsync(cloudEvent);

// 배치 전송
await senderClient.SendAsync(new[]
{
    new CloudEvent("source", "type", new { Name = "Alice" }),
    new CloudEvent("source", "type", new { Name = "Bob" })
});

이벤트 수신 및 처리

var receiverClient = new EventGridReceiverClient(
    new Uri(namespaceEndpoint),
    topicName,
    subscriptionName,
    new AzureKeyCredential(topicKey));

// 이벤트 수신
ReceiveResult result = await receiverClient.ReceiveAsync(maxEvents: 10);

List<string> lockTokensToAck = new();
List<string> lockTokensToRelease = new();

foreach (ReceiveDetails detail in result.Details)
{
    CloudEvent cloudEvent = detail.Event;
    string lockToken = detail.BrokerProperties.LockToken;
    
    try
    {
        // 이벤트 처리
        Console.WriteLine($"Event: {cloudEvent.Type}, Data: {cloudEvent.Data}");
        lockTokensToAck.Add(lockToken);
    }
    catch (Exception)
    {
        // 재시도를 위해 릴리스
        lockTokensToRelease.Add(lockToken);
    }
}

// 성공적으로 처리된 이벤트 확인
if (lockTokensToAck.Any())
{
    await receiverClient.AcknowledgeAsync(lockTokensToAck);
}

// 재시도를 위해 이벤트 릴리스
if (lockTokensToRelease.Any())
{
    await receiverClient.ReleaseAsync(lockTokensToRelease);
}

이벤트 거부 (Dead Letter)

// 처리할 수 없는 이벤트 거부
await receiverClient.RejectAsync(new[] { lockToken });

이벤트 소비 (Azure Functions)

EventGridEvent 트리거

using Azure.Messaging.EventGrid;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.EventGrid;

public static class EventGridFunction
{
    [FunctionName("ProcessEventGridEvent")]
    public static void Run(
        [EventGridTrigger] EventGridEvent eventGridEvent,
        ILogger log)
    {
        log.LogInformation($"Event Type: {eventGridEvent.EventType}");
        log.LogInformation($"Subject: {eventGridEvent.Subject}");
        log.LogInformation($"Data: {eventGridEvent.Data}");
    }
}

CloudEvent 트리거

using Azure.Messaging;
using Microsoft.Azure.Functions.Worker;

public class CloudEventFunction
{
    [Function("ProcessCloudEvent")]
    public void Run(
        [EventGridTrigger] CloudEvent cloudEvent,
        FunctionContext context)
    {
        var logger = context.GetLogger("ProcessCloudEvent");
        logger.LogInformation($"Event Type: {cloudEvent.Type}");
        logger.LogInformation($"Source: {cloudEvent.Source}");
        logger.LogInformation($"Data: {cloudEvent.Data}");
    }
}

이벤트 구문 분석

EventGridEvent 구문 분석

// JSON 문자열에서
string json = "..."; // Event Grid webhook 페이로드
EventGridEvent[] events = EventGridEvent.ParseMany(BinaryData.FromString(json));

foreach (EventGridEvent egEvent in events)
{
    if (egEvent.TryGetSystemEventData(out object systemEvent))
    {
        // 시스템 이벤트 처리
        switch (systemEvent)
        {
            case StorageBlobCreatedEventData blobCreated:
                Console.WriteLine($"Blob created: {blobCreated.Url}");
                break;
        }
    }
    else
    {
        // 사용자 지정 이벤트 처리
        var customData = egEvent.Data.ToObjectFromJson<MyCustomData>();
    }
}

CloudEvent 구문 분석

CloudEvent[] cloudEvents = CloudEvent.ParseMany(BinaryData.FromString(json));

foreach (CloudEvent cloudEvent in cloudEvents)
{
    var data = cloudEvent.Data.ToObjectFromJson<MyEventData>();
    Console.WriteLine($"Type: {cloudEvent.Type}, Data: {data}");
}

시스템 이벤트

// 일반적인 시스템 이벤트 유형
using Azure.Messaging.EventGrid.SystemEvents;

// Storage 이벤트
StorageBlobCreatedEventData blobCreated;
StorageBlobDeletedEventData blobDeleted;

// 리소스 이벤트
ResourceWriteSuccessEventData resourceCreated;
ResourceDeleteSuccessEventData resourceDeleted;

// App Service 이벤트
WebAppUpdatedEventData webAppUpdated;

// Container Registry 이벤트
ContainerRegistryImagePushedEventData imagePushed;

// IoT Hub 이벤트
IotHubDeviceCreatedEventData deviceCreated;

주요 유형 참조

유형용도
EventGridPublisherClient주제/도메인에 게시
EventGridSenderClient네임스페이스 주제로 전송
EventGridReceiverClient네임스페이스 구독에서 수신
EventGridEventEvent Grid 네이티브 스키마
CloudEventCloudEvents 1.0 스키마
ReceiveResult풀 전송 응답
ReceiveDetails브로커 속성이 포함된 이벤트
BrokerProperties잠금 토큰, 전달 횟수

이벤트 스키마 비교

기능EventGridEventCloudEvent
표준Azure 전용CNCF 표준
필수 필드subject, eventType, dataVersion, datasource, type
확장성제한적확장 속성
상호 운용성Azure 전용플랫폼 간

모범 사례

  1. CloudEvents 사용 — 새로운 구현에는 CloudEvents를 선호합니다 (업계 표준)
  2. 이벤트 배치 — 효율성을 위해 단일 호출로 여러 이벤트를 전송합니다.
  3. Entra ID 사용 — 액세스 키보다 관리 ID를 선호합니다.
  4. 멱등성(Idempotent) 핸들러 — 이벤트가 두 번 이상 전달될 수 있습니다.
  5. 이벤트 TTL 설정 — 네임스페이스 이벤트의 TTL(Time-to-Live)을 구성합니다.
  6. 부분 실패 처리 — 이벤트를 개별적으로 확인/릴리스합니다.
  7. Dead-letter 사용 — 실패한 이벤트에 대해 Dead-letter를 구성합니다.
  8. 스키마 유효성 검사 — 처리 전에 이벤트 데이터의 유효성을 검사합니다.

오류 처리

using Azure;

try
{
    await client.SendEventAsync(cloudEvent);
}
catch (RequestFailedException ex) when (ex.Status == 401)
{
    Console.WriteLine("인증 실패 - 자격 증명 확인");
}
catch (RequestFailedException ex) when (ex.Status == 403)
{
    Console.WriteLine("권한 부여 실패 - RBAC 권한 확인");
}
catch (RequestFailedException ex) when (ex.Status == 413)
{
    Console.WriteLine("페이로드가 너무 큼 - 이벤트당 최대 1MB, 배치 총합 최대 1MB");
}
catch (RequestFailedException ex)
{
    Console.WriteLine($"Event Grid 오류: {ex.Status} - {ex.Message}");
}

장애 조치 패턴

try
{
    var primaryClient = new EventGridPublisherClient(primaryUri, primaryKey);
    await primaryClient.SendEventsAsync(events);
}
catch (RequestFailedException)
{
    // 보조 지역으로 장애 조치
    var secondaryClient = new EventGridPublisherClient(secondaryUri, secondaryKey);
    await secondaryClient.SendEventsAsync(events);
}

관련 SDK

SDK용도설치
Azure.Messaging.EventGrid주제/도메인 (이 SDK)dotnet add package Azure.Messaging.EventGrid
Azure.Messaging.EventGrid.Namespaces풀 전송dotnet add package Azure.Messaging.EventGrid.Namespaces
Azure.Identity인증dotnet add package Azure.Identity
Microsoft.Azure.WebJobs.Extensions.EventGridAzure Functions 트리거dotnet add package Microsoft.Azure.WebJobs.Extensions.EventGrid

참조 링크

리소스URL
NuGet 패키지https://www.nuget.org/packages/Azure.Messaging.EventGrid
API 참조https://learn.microsoft.com/dotnet/api/azure.messaging.eventgrid
빠른 시작https://learn.microsoft.com/azure/event-grid/custom-event-quickstart
풀 전송https://learn.microsoft.com/azure/event-grid/pull-delivery-overview
GitHub 소스https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/eventgrid/Azure.Messaging.EventGrid

Individual skills in this repo

This repo contains 12 individual skills — each has its own dedicated page.

microsoft/azure-ai-agents-persistent-dotnet

Azure AI Agents Persistent SDK for .NET. Low-level SDK for creating and managing AI agents with threads, messages, runs, and tools. Use for agent CRUD, conversation threads, streaming responses, function calling, file search, and code interpreter. Triggers: "PersistentAgentsClient", "persistent agents", "agent threads", "agent runs", "streaming agents", "function calling agents .NET".

microsoft/azure-ai-document-intelligence-dotnet

Azure AI Document Intelligence SDK for .NET. Extract text, tables, and structured data from documents using prebuilt and custom models. Use for invoice processing, receipt extraction, ID document analysis, and custom document models. Triggers: "Document Intelligence", "DocumentIntelligenceClient", "form recognizer", "invoice extraction", "receipt OCR", "document analysis .NET".

microsoft/azure-ai-openai-dotnet

Azure OpenAI SDK for .NET. Client library for Azure OpenAI and OpenAI services. Use for chat completions, embeddings, image generation, audio transcription, and assistants. Triggers: "Azure OpenAI", "AzureOpenAIClient", "ChatClient", "chat completions .NET", "GPT-4", "embeddings", "DALL-E", "Whisper", "OpenAI .NET".

microsoft/azure-ai-projects-dotnet

Azure AI Projects SDK for .NET. High-level client for Azure AI Foundry projects including agents, connections, datasets, deployments, evaluations, and indexes. Use for AI Foundry project management, versioned agents, and orchestration. Triggers: "AI Projects", "AIProjectClient", "Foundry project", "versioned agents", "evaluations", "datasets", "connections", "deployments .NET".

microsoft/azure-ai-voicelive-dotnet

Azure AI Voice Live SDK for .NET. Build real-time voice AI applications with bidirectional WebSocket communication. Use for voice assistants, conversational AI, real-time speech-to-speech, and voice-enabled chatbots. Triggers: "voice live", "real-time voice", "VoiceLiveClient", "VoiceLiveSession", "voice assistant .NET", "bidirectional audio", "speech-to-speech".

microsoft/azure-eventhub-dotnet

Azure Event Hubs SDK for .NET. Use for high-throughput event streaming: sending events (EventHubProducerClient, EventHubBufferedProducerClient), receiving events (EventProcessorClient with checkpointing), partition management, and real-time data ingestion. Triggers: "Event Hubs", "event streaming", "EventHubProducerClient", "EventProcessorClient", "send events", "receive events", "checkpointing", "partition".

microsoft/azure-identity-dotnet

Azure Identity library for .NET. Authentication library for Azure SDK clients using Microsoft Entra ID. Use for DefaultAzureCredential, managed identity, service principals, and developer credentials. Triggers: "Azure Identity", "DefaultAzureCredential", "ManagedIdentityCredential", "ClientSecretCredential", "authentication .NET", "Azure auth", "credential chain".

microsoft/azure-kusto-graph

Build and query Kusto graphs from natural language. Covers transient graphs (make-graph), persistent graph models/snapshots, pattern matching (graph-match), shortest paths, connected components, and graph-to-table export. Generates the edges-first thinking: define edges, define node lookups, union, make-graph. WHEN: make-graph, graph-match, graph-shortest-paths, graph-to-table, graph-mark-components, persistent graph, graph model, graph snapshot, build a graph from data, find paths between nodes, pattern matching in graph, connected components, transient graph, Kusto graph, KQL graph.

microsoft/azure-kusto-irql

Compose IRQL (Incident Response Query Language) queries for Kusto cybersecurity investigations. Translates natural language hunting questions into composable IRQL pipelines using Get_*, Extract_*, and Enrich_* functions. WHEN: IRQL query, security hunt, threat hunting KQL, incident response query, compose hunting pipeline, failed logins, phishing investigation, lateral movement, process execution, file creation events.

microsoft/azure-kusto-irql-graph

Apply IRQL graph functions to KQL or IRQL query results for Kusto Explorer visualization. Generates Lift_To_Graph mappings and composes Graph_Render_View, Graph_Fold_By_Property, Extract_Node_*, Enrich_Node_*, and Enrich_Graph_* calls. Accepts a supplied query or limited basic natural-language source request; it is not a general natural-language-to-KQL/IRQL skill. WHEN: Lift_To_Graph, Graph_Render_View, Graph_Fold_By_Property, IRQL graph enrichment, graph mapping for existing query results, icon-decorated graph, fold graph nodes. Use azure-kusto-graph for native make-graph analysis, graph-match, shortest paths, components, or persistent graphs.

microsoft/azure-local

Plan, deploy, operate, and troubleshoot Azure Local (formerly Azure Stack HCI): sizing and prerequisites, Arc registration, lifecycle updates, workloads (Azure Local VMs, AKS on Azure Local, images, disks, logical networks), SDN and network security, and failure triage — starting read-only and confirming before risky changes. WHEN: Azure Local, Azure Stack HCI, Arc resource bridge, custom location, Azure Local VM, Arc VM, AKS on Azure Local, AKS hybrid, SDN, Lifecycle Manager, Azure Local update, disconnected site.

microsoft/azure-local-multi-rack

Plan, deploy, operate, and troubleshoot multi-rack (rack scale) deployments of Azure Local — preintegrated racks scaling to hundreds of machines, built on Network Fabric Controller, Cluster Manager, SAN storage, and managed network fabric. Use for the Microsoft.NetworkCloud and Microsoft.ManagedNetworkFabric control plane. NOT for standard 1-16 node Azure Local, and NOT for rack-aware clusters (two racks as availability zones, up to 8 nodes, synchronous replication) — those are standard scale. WHEN: multi-rack, rack scale Azure Local, aggregation rack, compute rack, Network Fabric Controller, NFC, Cluster Manager, network fabric, isolation domain, az networkcloud, az networkfabric, multi-rack logical network, multi-rack Arc VM.

관련 스킬