Microsoft really knows how to get me frustrated

While I was working on a walkthrough on authentication and authorization I decided to use the Microsoft Graph API as an example. In this example I wanted to use application permissions to list all users. Nothing special. Configured my application, wrote some code but… got an error message telling me that my application does not have the required permissions to read all users. So let’s go back to Azure and verify the permissions.

Azure Active Directory Permission Assignment
Azure Active Directory Permission Assignment

Looks pretty good. I actually do have some experience with authentication and authorization – which is why I’m writing this walkthough – but I do not have a clue about what I did wrong. No warning messages here. OK then, let’s search… and GitHub?! contains the answer. It appears that Microsoft decided that besides the permissions given by the administrator, the service principal also needs to be a “Company Administrator” (which you cannot configure from the UI) as a security measure. So the UI is just complete bogus without that role being assigned first. And another hour of my time is down the drain…

UPDATE:
To be consistent with not being consistent Microsoft does allow you to fetch all users if you use the BETA API (https://graph.microsoft.com/beta/users) as security in a public BETA – that is automatically enabled for everyone – apparently is not that important.

Redux…

I have mixed feelings about Redux. I really like the general ideas behind Redux, and how nice they’ve explained how and when to use it. I do not like the implementation however. The main reason for that, is that they invented their own vocabulary around existing design patterns. This distracts you from the patterns they use and that in turn complicates learning.

Why would one call something a “reducer” when it is in fact a “mediator”. Why would you call something an “action” when it is a “command”? The most important Redux framework method is called “dispatch” while it has nothing to do with events. As it invokes a command on the state, it should have been called “invoke” or “invokeCommand”. If they had done a better job on that it would have been clear that we are talking about a basic implementation of the Command pattern.

Another thing I struggle with is that they pass strings around to define which actual commands to execute. Inside the “dispatch” method they call the “reducer” which uses a switch statement to finally invoke the actual required command.

function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

This is very difficult to maintain and almost impossible to refactor. The only good part about it, is that you can easily serialize and store the list of executed “commands” and then deserialize and replay that list on the initial state, to get to the current state. How useful that is, depends on your application. I do think it is at least a bit smelly.

Eventually I decided to create my own predictable state container using TypeScript and standard design patterns.

My own predictable state container

Let’s start with the core.ts:

namespace Core {
    "use strict";

    export interface ICommand<S> {
        execute(state: S): S;
        undo(state: S): S;
    }

    export interface IInvoker<S> {
        invoke(command: ICommand<S>): void;
    }

    export interface IRecorder {
        canUndo: boolean;
        undo(): void;

        canRedo: boolean;
        redo(): void;
    }

    export interface IObservable {
        subscribe(callback: () => void): number;
        unsubscribe(id: number): void;
    }

    export interface IContext<S> {
        state: S;
    }

    interface ISubscription {
        id: number;
        callback: () => void;
    }

    export class Context<S> implements IContext<S>, IInvoker<S>, IObservable  {
        private _state: S;

        constructor(initialState: S) {
            this._state = initialState;
        }

        public get state(): S {
            return this._state;
        }

        protected setState(state: S): void {
            this._state = state;
            this.notify();
        }

        public invoke(command: ICommand<S>): void {
           const state: S = command.execute(this.state);
           this.setState(state);
        }

        private _subscriptionId = 0;
        private _subscriptions: ISubscription[] = [];

        public subscribe(callback: () => void): number {
            const id: number = ++this._subscriptionId;
            this._subscriptions.push({ id: id, callback: callback });
            return id;
        }

        public unsubscribe(id: number): void {
            this._subscriptions = this._subscriptions.filter((value: ISubscription) => {
                return value.id !== id;
            });
        }

        private notify(): void {
            this._subscriptions.forEach((value: ISubscription) => {
                value.callback();
            });
        }
    }

    export class RecordingContext<S> extends Context<S> implements IRecorder {
        private _commands: ICommand<S>[] = [];
        private _current: number = -1;

        constructor(initialState: S) {
            super(initialState);
        }

        public invoke(command: ICommand<S>): void {
            super.invoke(command);
            this._commands.splice(this._current + 1);
            this._current = this._commands.push(command) - 1;
        }

        public get canUndo(): boolean {
            return this._current >= 0;
        }

        public undo(): void {
            if (this.canUndo) {
                const command: ICommand<S> = this._commands[this._current--];
                const state: S = command.undo(this.state);
                this.setState(state);
            }
        }

        public get canRedo(): boolean {
            return this._current < this._commands.length - 1;
        }

        public redo(): void {
            if (this.canRedo) {
                const command: ICommand<S> = this._commands[++this._current];
                const state: S = command.execute(this.state);
                this.setState(state);
            }
        }
    }
}

The core consists of no more than a few interfaces and two generic classes. One class that maintains a list of executed commands, and one that does not. Why I like my implementation better is because I use the same commonly known design patterns, but with the standard vocabulary. Besides that my commands are also passed strongly typed. Which makes it refactorable and maintainable, and prevents you from making typo’s. The drawback is that they are not serializable anymore. Up to you to decide here. Compiled and minified to ECMAScript 6, the whole core takes up no more than 1kb.

Let’s have a look on how to use this core library when we create React.Components in a UI.tsx:

namespace UI {
    "use strict";

    export interface ICounterProps<S> {
        context: Core.Context<S>;
        getValue: (context: Core.Context<S>) => any;
        incrementCommand: Core.ICommand<S>;
        decrementCommand: Core.ICommand<S>;
    }

    export interface ICounterState {
        value: number;
    }

    export class Counter<S> extends React.Component<ICounterProps<S>, ICounterState> {
        private _subscription: number;

        constructor(props: ICounterProps<S>) {
            super(props);
            this.state = {
                value: this.props.getValue(this.props.context)
            };
        }

        public componentDidMount(): void {
            this._subscription = this.props.context.subscribe(() => {
                this.setState({
                    value: this.props.getValue(this.props.context)
                });
            });
        }

        public componentWillUnmount(): void {
            this.props.context.unsubscribe(this._subscription);
        }

        public render(): JSX.Element {
            const buttonStyle: React.CSSProperties = { minWidth: "50px" };
            const {context, incrementCommand, decrementCommand} = this.props;
            const {value} = this.state;

            return (<div>
                Value: {value}
                <div>
                    <button
                        style={buttonStyle}
                        onClick={() => context.invoke(incrementCommand)}>
                        +
                    </button>
                    <button
                        style={buttonStyle}
                        onClick={() => context.invoke(decrementCommand)}>
                        -
                    </button>
                </div>
            </div>);
        }
    }

    export interface IUndoRedoProps {
        context: Core.IRecorder & Core.IObservable;
    }

    export class UndoRedo extends React.Component<IUndoRedoProps, {}> {
        private _subscription: number;

        constructor(props: IUndoRedoProps) {
            super(props);
        }

        public componentDidMount(): void {
            this._subscription = this.props.context.subscribe(() => {
                this.forceUpdate();
            });
        }

        public componentWillUnmount(): void {
            this.props.context.unsubscribe(this._subscription);
        }

        public render(): JSX.Element {
            const buttonStyle: React.CSSProperties = { minWidth: "50px" };
            const {context } = this.props;

            return (<div>
                <button
                    style={buttonStyle}
                    disabled={!context.canUndo}
                    onClick={() => context.undo()}>
                    undo
                    </button>
                <button
                    style={buttonStyle}
                    disabled={!context.canRedo}
                    onClick={() => context.redo()}>
                    redo
                    </button>
            </div>);
        }
    }
}

The important part here is that we pass Core.ICommand<S> for binding to events instead of strings.

So let’s have a look at the App.tsx

namespace App {
    "use strict";

    const update: (value: any, spec: React.UpdateSpec) => any = React.addons.update;

    interface IState {
        number: number;
        char: string;
    }

    class Context extends Core.RecordingContext<IState> {
        constructor() {
            super({ number: 0, char: "a" });
        }
    }

    const Commands = {
        IncrementNumber: {
            execute: (state: IState): IState =>
                update(state, { number: { $set: state.number + 1 } }),
            undo: (state: IState): IState =>
                update(state, { number: { $set: state.number - 1 } })
        },
        DecrementNumber: {
            execute: (state: IState): IState =>
                update(state, { number: { $set: state.number - 1 } }),
            undo: (state: IState): IState =>
                update(state, { number: { $set: state.number + 1 } })
        },
        IncrementChar: {
            execute: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) + 1) } }),
            undo: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) - 1) } })
        },
        DecrementChar: {
            execute: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) - 1) } }),
            undo: (state: IState): IState =>
                update(state, { char: { $set: String.fromCharCode(state.char.charCodeAt(0) + 1) } })
        }
    };

    export function init(): void {
        const root: HTMLElement = document.getElementById("root");
        const context: Context = new Context();

        type Counter = new () => UI.Counter<IState>;
        const Counter: Counter = UI.Counter as Counter;

        ReactDOM.render(<div>
            <Counter
                context={context}
                getValue={(context: Context) => context.state.number}
                incrementCommand={Commands.IncrementNumber}
                decrementCommand={Commands.DecrementNumber} />
            <Counter
                context={context}
                getValue={(context: Context) => context.state.char}
                incrementCommand={Commands.IncrementChar}
                decrementCommand={Commands.DecrementChar} />
            <hr />
            <UI.UndoRedo
                context={context} />
        </div>
            , root
        );
    };
}

window.addEventListener("load", (ev: Event) => {
    App.init();
});

There are a lot of way’s to define commands now. In the above example I’ve created a const Commands object that contains the command objects as I do not need any per command state or properties. You could of course do something like this to define a custom command just as well:

class CustomIncrementCommand implements Core.ICommand<IState> {
    private properties:ICustomIncrementCommandProps;
    constructor(properties: ICustomIncrementCommandProps) {
        this.properties = properties;
    }

    public execute(state: IState): IState {
        return update(state, { number: { $set: state.number + properties.incrementValue} });
    }

    public undo(state: IState): IState {
        return update(state, { number: { $set: state.number - properties.incrementValue} });
    }
}

You could then pass the constructor to your components and in the component itself, create a new instance of the command, with the properties based on the current component state.

All in all we now have a complete, generic, strongly typed predictable state container using TypeScript and standard design patterns, that also uses the proper vocabulary.

UPDATE:
That same friend asked me if he should now use my implementation of a predictable state container or the standard Redux implementation. That should be the Redux implementation of course! There are a lot of people working on maintaining Redux and there are a lot of (browser)plugins that you can use with the standard Redux implementation. The value of Redux is not just in Redux itself, but also the eco-system around it. The reason I wrote this article and a sample on how I would do it, is just because I think that if they’d at least adhered to the standard design patterns, it would have been a lot easier to learn how to use Redux.

Have fun,

Wesley

Who needs documentation?

While working on a solution that is supposed to list Azure Resources using client side code, I came into contact with Azure Resource Manager REST API. And honestly this is a pretty awesome collection of API’s! Now the whole issue with this API is that it is actually a constantly changing collection of API’s and that there is no documentation available at all. How useful is that?

Sure they’ve written an article with the title “Azure Resource Manager REST API Reference”, but it contains high level information only. They actually tell you that the best way you can find out what will be returned by the API, is by using a tool they call Azure Resource Explorer.

The first issue I have with that, is that you can only execute calls on resources that you’ve got in your Azure Subscription. So if you would like to find out what response will be returned when you request information on a Storage Resource, you will first have to create such a resource in your Azure Subscription. You can then use the Azure Resource Explorer, to see the JSON result returned. This will tell you nothing of course about the actual schema that you can expect.

The second issue I have with that, is that I have no way of creating a decent client side proxy with something like T4 templating. So it took me a couple of weeks to create a client side proxy to get only the basic information and it’s all based on guessing. Good job Microsoft!

Did nobody at Microsoft every heard about something like Swagger?

UPDATE:
Microsoft did hear about Swagger! Their own PowerApps product can connect to custom API’s as long as you can provide the definition file in… Swagger format! But wait. “Does that mean that I cannot connect to Microsoft’s own Graph API to fetch person details into my PowerApp unless I create the Swagger definition file manually?” Yes… sigh.