Skip to content
Duncan Jones edited this page May 22, 2021 · 11 revisions

Event Sourcing on Azure Functions

Introduction

This project demonstrates Event Sourcing as a persistence mechanism for Azure "Serverless" Functions.

Each entity in the system is backed by an event stream, being the complete ordered history of all the events that have occurred to that entity. Functions which modify the state of an entity (commands) do so by appending one or more events onto the end of that event stream and functions which get state (queries) do so by running a projection over that event stream that evaluates the current state of the properties that it requires.

How to use this library

Updating an entity (Command functions)

To update the state of an entity you need to create an instance of the eventstream class with the identity of the entity to be updated and then append one or more events to its event stream to effect the change.

This can be done using the eventstream binding attribute to have the event stream class created by dependency injection when the azure function is instantiated.

Getting the state of an entity (Query functions)

To get the state of an entity you need to create an instance of the projection class with the identity of the entity to be queried and the name of the projection to run over the event stream to retrieve that state.

This can be done using the projection binding attribute to have the specific projection class created by dependency injection when the azure function is instantiated.

The connection string(s) to use to connect to the backing storage mechanism are read from the environment variables (and can therefore be set by the Azure portal for your functions application) or if not present there they can be read from your .config files. (NB: If they are stored in config files be careful not to add these to any public source control)

As well as the connection strings, there are two aspects of the system configuration that can be changed without recompiling or redeploying the function app. that uses this event sourcing library: Event Stream Settings are the settings that describe how the physical data underlying an event stream are stored and Event Maps which defines how event names (in business terms) are mapped to .NET classes.

In the latter case this can also be set at compile time with the EventName attribute.

The run time configuration is via environment strings where the key is the identifier of the event stream and the value is the setting in ; separated format.

e.g. Bank.Account = Table;Bank.Account.ConnectionStringName You can replace the domain or entity type names with ALL to apply a global setting e.g.:- Bank.ALL = Table;RetailBankTableConnectionString

How it works

Event streams overview

An event stream is the sequential history of all the events that have occurred to an entity over its life history. (More detail in this overview)

Projections overview

A projection is a piece of code that runs over the event stream for an entity in order to derive some state information about that entity. (More detail in this overview)

Notifications overview

Notification messages are published when an event is saved to an event stream or when a projection is run, and these can be used to connect together different parts of a serverless system swarm. (More detail in this overview)

Azure Table implementation

In this implementation the domain and entity type specify the specific table that the event stream is stored in and the unique entity instance identifier is the partition key in that table. Events are stored in that table with the sequence number (incremental and zero padded) stored in the row key.

AppendBlob implementation

In this implementation each entity gets its own event stream in a blob where the path and filename reflect the combination of domain, entity type and unique entity instance identifier. Events are stored in JSON and appended to the end of the blob.