Azure Event Grid’s trigger functions let you react to events happening across your Azure services and even your own applications. The most surprising thing is that Event Grid doesn’t push events; it announces them, and your functions then pull (or rather, are notified) to process them.
Imagine you have a new image uploaded to a Blob Storage container. Event Grid can detect this "Microsoft.Storage.BlobCreated" event and, instead of you constantly polling for new blobs, it can send a notification to a specific endpoint – like an Azure Function. This is where the magic happens. Your Azure Function, configured as a subscriber to this event, receives the event payload, which contains all the details about the new blob (its name, URL, size, etc.).
Here’s a simplified look at an Azure Function triggered by Event Grid. This C# example shows how to receive and process a StorageBlobCreated event.
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.EventGrid;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
public static class EventGridBlobTrigger
{
[FunctionName("EventGridBlobTriggerFunction")]
public static void Run(
[EventGridTrigger] EventGridEvent eventGridEvent,
ILogger log)
{
log.LogInformation($"Event Type: {eventGridEvent.EventType}");
log.LogInformation($"Subject: {eventGridEvent.Subject}");
log.LogInformation($"Event Time: {eventGridEvent.EventTime}");
// Deserialize the event data
var eventData = JsonConvert.DeserializeObject<StorageBlobCreatedEventData>(eventGridEvent.Data.ToString());
log.LogInformation($"Blob URI: {eventData.Url}");
log.LogInformation($"Blob Size: {eventData.Size}");
// Your processing logic here, e.g., resizing the image, analyzing content, etc.
// For example, you might use eventData.Url to get the blob and perform operations.
}
}
// Helper class to deserialize the specific event data for BlobCreated
public class StorageBlobCreatedEventData
{
public string Api { get; set; }
public string ClientRequestId { get; set; }
public string RequestId { get; set; }
public string Version { get; set; }
public string BlobUri { get; set; } // Note: Event Grid often uses BlobUri, but the actual data might map to Url
public string Url { get; set; } // This is what you'll typically see in the event payload
public long Size { get; set; }
public string ContentType { get; set; }
}
The core of this is the [EventGridTrigger] attribute. This tells the Azure Functions runtime to expect incoming Event Grid events. When an event matching the function’s configuration arrives, the runtime invokes this function, passing the EventGridEvent object. This object contains metadata about the event (type, subject, timestamp) and the actual event data, which is often a JSON payload specific to the event source.
When you set up an Event Grid subscription, you define:
- Topic: The source of the event (e.g., a specific Storage Account, a Resource Group, or a custom topic you’ve created).
- Event Type(s): The specific events you want to subscribe to (e.g.,
Microsoft.Storage.BlobCreated,Microsoft.Resources.CreatedOrUpdated). - Endpoint: Where the event notification should be sent. In this case, it’s the HTTP endpoint of your Azure Function. Event Grid uses a webhook mechanism to deliver these notifications.
- Filter (optional): You can narrow down the events based on subjects, prefixes, or suffixes.
The real power comes from decoupling. Your storage account doesn’t need to know about your function. It just fires an event. Event Grid, acting as a central nervous system, routes that event to all registered subscribers. This makes your architecture incredibly scalable and resilient. If your function is temporarily unavailable, Event Grid will retry delivery (with a configurable retry policy) until it succeeds or the retry limit is reached, preventing data loss.
The EventGridEvent object itself is a standard structure, but the Data property is where the real specifics lie. For Microsoft.Storage.BlobCreated events, the Data property is a JSON object containing details like Url (the blob’s URI), Size, and ContentType. Your function’s code needs to deserialize this JSON into a specific C# class (like StorageBlobCreatedEventData shown above) to access these details.
A subtle point that trips many up is how Event Grid handles delivery guarantees to webhooks like Azure Functions. Event Grid guarantees "at-least-once" delivery. This means your function might receive the same event more than once. You must design your function to be idempotent – meaning processing the same event multiple times should have the same effect as processing it once. For example, if your function is to copy a blob, ensure that attempting to copy an already copied blob doesn’t cause errors or duplicate data. You can achieve idempotency by tracking processed event IDs or by using operations that are inherently safe to repeat.
By leveraging Event Grid triggers, you can build event-driven architectures that are highly responsive and efficient, reacting to changes in your Azure environment in near real-time without constant polling.
The next step is often to explore custom Event Grid topics, allowing you to publish events from your own applications and build sophisticated event-driven workflows across services.