Serverless CQRS in Azure

Part 1: Introduction, Commands & Event sourcing

This is a multi-part article. In the coming weeks I’ll be publishing more articles to cover Projection Processing, Querying Materialized Views and a comparison with an Azure Functions approach.

Introduction

Keen to explore the realms of what is possible with Azure’s Serverless technologies, I decided there was no better way than to attempt to tackle a complex, modern software pattern: Command Query Responsibly Segregation, otherwise known as CQRS (with event sourcing & materialized views thrown in for good measure).

CQRS

In a nutshell, CQRS is a pattern that can be used where high throughput is required that would otherwise not be possible for traditional CRUD operations often found in an N-tier architecture using something like the repository pattern. As a system, it looks something like this:

Event sourcing & Materialized views

These are two patterns that work very well with CQRS. The idea for event sourcing is that you store only events and use the event store as a mechanism, or log, of everything that has happened within a system. This event store can then be used to create materialized views (at any point in time) to reconstruct the current state of a query-able view from the read store. More information can be found here:

The Problem

Imagine a world where someone had the foresight to create some electric cars and a network of places to charge them. Perhaps you might want to call them superchargers, and maybe they would look like this: https://www.tesla.com/supercharger. The scenario I set myself was that I’m creating a global database to:

Architecture

It is in fact possible to build some pretty complex workflows in Logic Apps and hence it should be possible to aim for a no-code target architecture like so:

Commands and Event sourcing

In order to stay true to the no-code challenge I set myself there are some decisions that had to be made about the system. First, there would be no ORM and no SQL database. Commands would be received as JSON objects, validated as JSON schema, manipulated as JSON and stored as, you guessed it, JSON documents. A great excuse to use Cosmos DB then.

  • inuse
  • notinuse
  • serviced
  • decomissioned
{  "type": "object",  "properties": {    "command_name": {      "type": "string",      "required": true    },    "received": {      "type": "string",      "format": "date-time",      "required": true    },    "command": {      "type": "object",      "properties": {        "supercharger_serial": {        "type": "string",        "required": true       }.....
....."command": {  "type": "object",  "properties": {    "location_name": {      "type": "string",      "required": true      },   "supercharger_type": {      "type": "string",      "required": true    },  "supercharger_serial": {    "type": "string",    "required": true    },    "lat": {      "type": "number",      "required": true    },    "long": {      "type": "number",      "required": true    }.....

The Logic App

I will be building one of these:

  • Event Grid Topic
  • Cosmos DB
  • Logic App
  • body — gets the body property of the named step
  • guid — generates a new guid

@richgojames. Cloud | Dev | Tech | Lead

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store