Azure Event Grid series: CloudEvents Schema
Tags: azure, eventgrid, cloudevents, eventdriven
Published: 2020-12-21 12:08:51

This is a series of blogs to talk and discuss about good practices and tips for Event Grid. Some of the topics that will be discussed can be applied not only to Event Grid but also to any other event/message based service.

## TL;DR

CloudEvents is an open source project which goal is to provide a common way for describing event data. It is possible to work with Azure Event Grid and CloudEvents but some processes are different, for example the Webhook Subscription Validation.

## Event Schemas

An **Event Schema** defines the structure of an event, the formatting and some specific behaviors, for example, the way an event subscription is validated. The structure of an event is represented by the different properties that are present on an event. For each property, it must define if it is required, the type of the property (string, timestamp, object, etc), the purpose of the property and its constraints (max length, uniqueness, etc).

Azure Event Grid supports three different schemas. The schema must be specified on both Event Grid Topic and Event Grid Subscriber:

- **Event Grid Schema:** it is the default schema. It is defined by Microsoft and the specification can be found [here](https://docs.microsoft.com/en-us/azure/event-grid/event-schema).

- **Custom Schema:** it enables users to define its own schema. It can be used to integrate an existing event-based system.

- **CloudEvents Schema:** it is an open specification for describing event data.

> NOTE: By now, both schemas (topic and subscriber) must match.

## CloudEvents Schema v1.0

CloudEvents is an open specification for describing event data in a common way. It is hosted by the [Cloud Native Computing Foundation (CNCF)](https://www.cncf.io/). It is important to highlight this last point since having such a large foundation supporting and working on CloudEvents ensures a long term life for the open source project.

Working with CloudEvents provides some benefits:

- **Portability:** it makes easier to switch from one event service provider to other when both support CloudEvents.

- **Accessibility:** providing common [SDKs](https://github.com/cloudevents/spec#sdks) in different languages to ease the usage of CloudEvents.

### Event Structure

CloudEvents provides a detailed specification of the event data. It can be found on [here](https://github.com/cloudevents/spec/blob/v1.0/spec.md).

```json
{
    "specversion" : "1.0",
    "type" : "com.github.pull.create",
    "source" : "https://github.com/cloudevents/spec/pull",
    "subject" : "123",
    "id" : "A234-1234-1234",
    "time" : "2018-04-05T17:31:00Z",
    "comexampleextension1" : "value",
    "comexampleothervalue" : 5,
    "datacontenttype" : "text/xml",
    "data" : "<much wow=\"xml\"/>"
}   
```

### Http Webhook

As mentioned in a [previous post](https://dev.to/davidgsola/tips-and-tricks-for-azure-event-grid-authenticate-webhook-subscriptions-37cn) from this series, a Webhook subscription must prove that it knows how to handle events before receiving them. This proving step is usually known as subscription validation process. Each event schema might define its own validation process, for example, when using **EventGrid Schema** the webhook endpoint receives a **POST** request with a validation code on the payload, that code must be returned on a specific response field.

CloudEvents defines the [validation process](https://github.com/cloudevents/spec/blob/v1.0/http-webhook.md#41-validation-request) in detail. In this case, it sends an **OPTIONS** request with a `Webhook-Request-Origin` header. It expects a response with that header value on a `Webhook-Allowed-Origin` header. Additionally, it can define the notification rate limitation using `WebHook-Allowed-Rate` header.

### Code sample

You can find in this repository a code sample of an Azure Function subscribed to a Event Grid Topic using CloudEvents v1.0 schema: https://github.com/DavidGSola/event-grid-good-practices/tree/main/cloud-events-schema/CloudEventSubscriber