What is Event Sourcing?

Event Sourcing

Every application has a state, representing current snapshot at the moment. Event sourcing is the idea of persisting all of these states as it changes from one to another.

Imagine a workflow for an invoice goes something like: invoice is created which set the status to pending. Pending invoice then gets approved which sets it approved. Approved invoice can be denied or collected. When invoice is denied, it goes back to pending, but when it’s collected, it becomes closed. The state of an invoice is where it’s at a particular time. However, when event sourcing pattern is implemented, we will be able to see a historical timeline of an invoice, from when it’s created to the current state.

What this allows us to do is, we are able to:

  • Complete rebuild: getting rid of the current state and use events to rebuild the invoice to its current state.
  • Temporal query: we can tell what state an invoice is at particular point in time.
  • Event replay: when the past event is incorrect, we can make the change and compute it from the beginning, thus, replaying the whole series of events.

Some applications of event sourcing are:

  • Source control. Every source control uses time series where commits made change the code. By storing events for every commit, we are able to state of the code at particular point in time.
  • Redo / undo. Applications that utilize undo / redo, such as word processor, will benefit from event sourcing pattern.
  • Document history. Word processor application will also benefit from event sourcing by storing event every time changes are made.

I hope this simple explanation of event sourcing helps you to understand what it is and how we can use it. There’s definitely a lot more to it that I don’t cover here, but there are lots of resources online you can learn from.

Reference

https://martinfowler.com/eaaDev/EventSourcing.html

Barebone Angular Project with Auth0

Simple project to demonstrate how to use Auth0 in Angular project, download code on Github.

To get started, you must have Auth0 account.
To setup the project, update following value in `environment.ts`:
1. Client ID. This is the id of your app you created in Auth0 dashboard. See here.
2. Client Domain. Your Auth0 domain to authenticate user. See here.
3. Callback Url. This is url Auth0 will redirect to after user is authenticated. This url must be white-listed in Auth0 dashboard. See here.
4. Logout Url. This is url Auth0 will redirect to after user logout. This url must be white-listed in Auth0 dashboard. See here.

The juice is on `service/auth.service.ts`, following are explanations of each methods:
1. Login
Call Auth0 authorize method to authenticate users. The method will redirect user to Auth0, if user is not authenticated, a login screen will displated, if user is authenticated Auth0 will redirect to callback endpoint and pass id token.

2. HandleAuthentication
Parse response object from Auth0 which contain id token, access token, expiration time and other information. Redirect user to appropriate url depend on the authorization results.

3. SetSession
Set authentication tokens and expiration in browser’s storage. User is authenticated.

4. Logout
Remove authentication tokens and expiration from browser’s storage. User is not authenticated anymore.

5. IsAuthenticated
Check browser’s storage to see if user is authenticated.

BuzzWord: Functional Programming Short Guides

This is summary of: Anjana Vakil’s video

1. Do everything with functions. Function take input and return output.
Non functional

var name = “Anjana”;
var greeting = “Hi, I’m ”;
console.log(greeting + name);
// Output: “Hi, I’m Anjana”

Functional

function greet(name) {
    return “Hi, I’m ” + name;
}
greet(“Anjana”);
// Output: “Hi, I’m Anjana”

2. Avoid side effects. Function should only process input it is given and return output, everything else is distractions (ie: process global variables, run command not intended to process input, etc). This is pure functions.
Not pure

var name = “Anjana”;
function greet() {
    console.log(“Hi, I’m ” + name);
}

Pure

function greet(name) {
    return “Hi, I’m ” + name;
}

3. Could have higher-order functions. Inputs and outputs can be functions.

function makeAdjectifier(adjective) {
    return function (string) {
        return adjective + “ ” + string;
    };
}

var coolifier = makeAdjectifier(“cool”);
coolifier(“conference”);
// Output: "cool conference"

4. Don’t iterate. Instead of iterate, use functions (map, reduce, filter).
Iterate

var fruits = ["apple", "orange", "banana"];
var goodFruits = [];
for (var i = 0; i  fruit + " great");
// Output: ["apple great", "orange great", "banana great"]

5. Avoid mutability objects. Unintended changes to objects could cause confusion and introduce bugs. Instead, use immutable objects.
Mutable

var rooms = [“H1”, “H2”, “H3”];
rooms[2] = “H4”;
// Output: ["H1", "H2", "H4"]

Immutable objects with function

var rooms = [“H1”, “H2”, “H3”];
var newRooms = rooms.map(function (rm) {
    if (rm == “H3”) {
        return “H4”;
    } else {
        return rm;
    }
});
// Output: rooms => ["H1", "H2", "H3"]
// Output: newRooms => ["H1", "H2", "H4"]

6. Persistent data structure for efficient immutability.
Instead of copying immutable objects which take time and memory (space) for every single copy, use persistent data structure that treat object as nodes and connect them in tree structure, changes of objects will only affect certain nodes, not entire object. This can be achieved with third party framework such as Mori or Immutable.js

SQL Server Configuration Manager: “Cannot connect to WMI provider. You do not have permission”

This caused by uninstalling certain version of SQL Server and re-installing different version.

See this for fixes.

Note: Run command prompt as Administrator.

WebApi ExceptionHandling.ExceptionHandler Sometimes Does Not Handle Global Exception. What ?!

See previous post on how to implement ExceptionHandler.

ExceptionHandler supposed to handle exception globally, but sometimes it does not… what ?!

There are few cases where ExceptionHandler will not capture exception. One of them is when CORS is enabled, see this.

To ensure ExceptionHandling to always capture exception, try:
1. If inherit from ExceptionHandler, override its method `ShouldHandle()`.

        public override bool ShouldHandle(ExceptionHandlerContext context)
        {
            return true;
        }

2. Instead of ExceptionHandling.ExceptionHandler, inherit and implement it’s interface `ExceptionHandling.IExceptionHandler`.