Azure Event Grid Concepts
Event Routing and Event-Driven Architecture
Introduction
Azure Event Grid is a fully managed event routing service that enables you to build event-driven architectures. It connects event sources to event handlers, making it easy to react to state changes across your applications and services.
This comprehensive guide covers:
- Core components — Topics, subscriptions, handlers
- Event structure — Understanding event schema
- Event types — System vs custom events
- Delivery patterns — Push-based event delivery
- Filtering — Event routing based on content
Architecture Overview
How Event Grid Works
┌─────────────────────────────────────────────────────────────────────┐
│ EVENT GRID ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Event │ Event │ Event │ │
│ │ Source │ Topic │ Handler │ │
│ │ │ │ │ │
│ │ ┌─────────┐ │ │ ┌────────────────┐ │ │
│ │ │ Storage │ │─────── Events ──────▶│ │ Azure │ │ │
│ │ │ │ │ │ │ Functions │ │ │
│ │ └─────────┘ │ │ └────────────────┘ │ │
│ │ │ │ │ │
│ │ ┌─────────┐ │ │ ┌────────────────┐ │ │
│ │ │ Cosmos │ │ │ │ Logic Apps │ │ │
│ │ │ DB │ │ │ └────────────────┘ │ │
│ │ └─────────┘ │ │ │ │
│ │ │ │ ┌────────────────┐ │ │
│ │ ┌─────────┐ │ │ │ Webhooks │ │ │
│ │ │ Custom │ │ │ └────────────────┘ │ │
│ │ │ App │ │ │ │ │
│ │ └─────────┘ │ │ │ │
│ └──────────────┘ └──────────────────────┘ │
│ │
│ Event Grid Topic ─── Filters events ─── Routes to handlers │
│ │
└─────────────────────────────────────────────────────────────────────┘
Event Grid Components
Topics
Topics act as the endpoint where publishers send events. There are two types:
System Topics
- Built-in topics for Azure services
- Automatically created when you subscribe to Azure service events
- Examples: Storage, Cosmos DB, Service Bus, Event Hubs
Custom Topics
- Created by users for application events
- Fully controlled by the developer
- Used for custom application events
Event Subscriptions
A subscription defines:
- Which events to receive (filters)
- Where to send events (endpoint)
- How to deliver events (delivery options)
Event Handlers
The final destination for events:
- Azure Functions
- Logic Apps
- Webhooks (HTTP endpoints)
- Azure Event Hubs
- Azure Service Bus Queues/Topics
- Storage Queues
Event Structure
Event Schema
{
"id": "event-id-12345",
"subject": "orders/12345",
"eventType": "order.created",
"eventTime": "2024-01-15T10:30:00Z",
"data": {
"orderId": "12345",
"customerId": "cust-001",
"total": 99.99,
"items": [
{"productId": "prod-1", "quantity": 2}
]
},
"dataVersion": "1.0",
"metadataVersion": "1"
}
Event Properties
| Property | Description | Required |
|---|---|---|
id | Unique event identifier | Yes |
subject | Event source path | Yes |
eventType | Type of event | Yes |
eventTime | Timestamp of event | Yes |
data | Event payload | Yes |
dataVersion | Version of data schema | No |
topic | Source of the event | No |
CloudEvents Schema
{
"specversion": "1.0",
"type": "order.created",
"source": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Storage/storageAccounts/myaccount",
"id": "event-id-12345",
"time": "2024-01-15T10:30:00Z",
"data": {
"orderId": "12345"
}
}
Creating and Managing Topics
Create Custom Topic
# Create Event Grid topic
az eventgrid topic create \
--name orders-topic \
--resource-group my-rg \
--location eastus \
--input-schema CloudEventSchemaV1_0
# Get topic endpoint
az eventgrid topic show \
--name orders-topic \
--resource-group my-rg \
--query "endpoint"
# Get topic key
az eventgrid topic key show \
--name orders-topic \
--resource-group my-rg \
--query "key1"
Topic Properties
// Topic configuration
var topicOptions = new TopicProperties
{
InputSchema = EventGridEvent.Schema, // or CloudEventV1Schema
PublicNetworkAccess = "Enabled",
InboundIpRules = new List<InboundIpRule>
{
new InboundIpRule("192.168.1.0/24", "Allow")
}
};
Publishing Events
.NET SDK
using Azure.Messaging.EventGrid;
// Create publisher client
var topicCredential = new AzureKeyCredential("your-topic-key");
var publisher = new EventGridPublisherClient(
new Uri("https://orders-topic.eastus-1.eventgrid.azure.net"),
topicCredential);
// Create event
var orderEvent = new EventGridEvent(
subject: "orders/12345",
eventType: "order.created",
dataVersion: "1.0",
data: new
{
orderId = "12345",
customerId = "cust-001",
total = 99.99
});
// Send event
await publisher.SendEventAsync(orderEvent);
// Send multiple events
var events = new EventGridEvent[]
{
new EventGridEvent(...),
new EventGridEvent(...)
};
await publisher.SendEventsAsync(events);
REST API
curl -X POST https://orders-topic.eventgrid.azure.net/api/events \
-H "Content-Type: application/json" \
-H "aeg-sas-key: your-topic-key" \
-d '[
{
"id": "12345",
"subject": "orders/12345",
"eventType": "order.created",
"eventTime": "2024-01-15T10:30:00Z",
"data": {
"orderId": "12345"
},
"dataVersion": "1.0"
}
]'
Subscribing to Events
Create Subscription
# Webhook subscription
az eventgrid event-subscription create \
--name order-handler \
--resource-group my-rg \
--topic-name orders-topic \
--endpoint-type webhook \
--endpoint https://myfunction.azurewebsites.net/api/handler
# Azure Function subscription
az eventgrid event-subscription create \
--name order-function \
--resource-group my-rg \
--topic-name orders-topic \
--endpoint-type azurefunction \
--endpoint /subscriptions/.../resourceGroups/.../providers/Microsoft.Web/sites/myfunction/functions/handler
Filter Events
# Filter by event type
az eventgrid event-subscription create \
--name order-created \
--resource-group my-rg \
--topic-name orders-topic \
--endpoint https://myfunction.azurewebsites.net/api/handler \
--filter-include-subject-pattern "orders/*" \
--filter-event-type-string order.created
Subscription Filters
{
"filters": {
"subjectBeginsWith": "orders/",
"subjectEndsWith": ".pdf",
"includedEventTypes": ["order.created", "order.updated"],
"advancedFilters": [
{
"key": "data.total",
"operatorType": "GreaterThan",
"value": 100
}
]
}
}
Event Handlers
Azure Functions
[FunctionName("OrderEventHandler")]
public async Task Run(
[EventGridTrigger] EventGridEvent eventGridEvent,
ILogger log)
{
log.LogInformation($"Event Type: {eventGridEvent.EventType}");
log.LogInformation($"Subject: {eventGridEvent.Subject}");
switch (eventGridEvent.EventType)
{
case "order.created":
await HandleOrderCreated(eventGridEvent.Data);
break;
case "order.updated":
await HandleOrderUpdated(eventGridEvent.Data);
break;
}
}
Logic Apps
{
"trigger": {
"type": "EventTrigger",
"inputs": {
"topic": "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.EventGrid/topics/orders-topic"
}
},
"actions": {
"Send_Email": {
"type": "Office365",
"inputs": {
"body": {
"Subject": "New Order",
"Body": "@triggerBody()"
}
}
}
}
}
Delivery and Retry
Retry Policy
{
"retryPolicy": {
"maxDeliveryAttempts": 3,
"eventTimeToLive": "PT1H"
}
}
Dead Letter
{
"deadLetterDestination": {
"endpointType": "StorageBlob",
"properties": {
"resourceId": "/subscriptions/.../storageAccounts/mystorage",
"blobContainerName": "eventgrid-deadletter"
}
}
}
Best Practices
| Practice | Description |
|---|---|
| Use CloudEvents | Industry-standard format |
| Implement retry | Handle transient failures |
| Use dead letter | Capture failed events |
| Filter appropriately | Only subscribe to needed events |
| Monitor delivery | Track delivery status |
Security
# Enable managed identity on topic
az eventgrid topic update \
--name orders-topic \
--resource-group my-rg \
--identity system-assigned
Related Topics
- Blob Events — Storage event handling
- Custom Topics — Custom event publishing
- Service Bus Events — Service Bus integration
Azure Integration Hub - Intermediate Level