Microsoft Flow as a front-end for your next application

Lately, I've built an application for quickly taking notes. And I've built its front-end in Microsoft Flow. Here is why.

Personal log

Recently, I wanted to build an application that I could use to easily write down things on my mind. I'd be using the application whenever and wherever and the only device I have on me at almost all times, is my phone. The nature of the notes would be personal so the data, as well as the access to the application, would have to be secure. Here is the architecture I came up with.

Let's go through it from right to left.

Data storage

To store the data, I chose Azure Table Storage. It's low entry, extremely easy to set up and doesn't cost much to use. To store the data, a single table would be sufficient. The data model would be very simplistic consisting of nothing more than the note itself and the date when it was taken.

Data access

To access the data in Azure Table Storage, I decided to use Azure Functions. I'm a big fan of serverless: it's quick to stand up and no maintenance. If you choose to, you can edit them directly in the browser. If you need a more managed experience, you can opt-in for a model backed by DevOps.

Azure Functions have rich integration capabilities allowing you to quickly tie into whatever data storage and APIs you might need to interact with. Additionally, they have powerful security and scalability capabilities sufficient for every scenario.

Viewing the data

While I wouldn't be viewing the data daily, I wanted to have the ability to have a look at it if need be. For that, I thought of building a React single-page app (SPA) hosted on an Azure Web App. I know React from the SharePoint Framework and a SPA with a single view would be sufficient for my needs.

Alternatively, I could've chosen a PowerApp, but for a side project that I wanted to have operational quickly, I went with what I already knew.

Writing the data

As the main interface, where I would be taking notes I chose... Microsoft Flow. You haven't quite expected it, have you? But before you dismiss my decision, let me tell you why.

Before Microsoft released Microsoft Flow, I was big on doing stuff in Azure Functions. Whatever API I had to implement, I'd do it in Functions. Some things were pretty straight forward. But I remember it like yesterday when once I wanted to integrate with SendGrid to be able to send an e-mail. I don't know how many hours I wasted finding just the right way to do it. In comparison, I've achieved the same thing (API sending an e-mail) with Microsoft Flow in a matter of minutes. Sure, you could argue that Flow doesn't support ALM, CI/CD, etc, but in some cases, it doesn't matter. Sometimes, good is good enough. Also, Azure Functions is just an API, there is no UI to it, so to use it for data entry you would need to combine it with PowerApp or a web app.

I could've implemented the UI in the React SPA that I already had. That would mean, however: a) more effort and b) that whenever I wanted to post a note, I'd need to authenticate to the website with my org account. With the current setup, I can start a Flow directly from my phone and with just a few taps write down whatever I had in mind.

When building a Flow you can choose a number of triggers. When you choose a manual trigger, you can configure a number of inputs making up a great alternative for a fully-fledged UI.

Security

As I mentioned, the nature of the whole application is highly personal, so all the data must stay secure at all times. With an architecture based on the Microsoft cloud that's not a problem. Here is what I've decided to use.

Data

The data in the Azure Table Storage cannot be accessed directly so it's secure by default.

Flow

Because my Flow is triggered manually and is not shared with anyone, there is no other way to start it than using my organizational Azure AD account. Unless you would steal my phone... and my face or my device pin along with it.

React SPA

To secure the React SPA from unauthorized access, I chose to use the App Service Security settings. I created a custom Azure AD which I locked down to allow only users from my Office 365 tenant (my Azure subscription and Office 365 belong to two separate AADs). All of this done through the Azure Portal.

API

As I mentioned, the communication with the data would be done through an Azure Function. Using its integration capabilities I connected the Azure Function to the Storage account and selected access to my table. Using this approach, the Azure portal automatically took care of configuring and storing the necessary connection string and my code stayed simple as I didn't need to worry about the plumbing of establishing the connection with the Table Storage.

The API would expose two operations: retrieving all data as well as adding new notes. To keep it safe, I decided to secure the Function using a Function Key. Using Azure AD to secure the Function would be overdoing it, given the Function is not exposed publicly and only used from the Flow and the web app which itself is secured with Azure AD.

Lessons learned

If you'd ask me how I'd architect a similar application last year, I'd give you a totally different answer. But it turns out, that for simplistic scenarios, where you need a solution quickly and good is good enough, using a manually triggered Flow with custom inputs has its place. Combined with the capabilities of Microsoft Azure, you can build a functioning solution that's also secure!

The next time I'd be something similar I might try using PowerApps instead of Flows as the main interface. It would allow me to combine entering and viewing data in a single UI. It would be an interesting lesson is interacting with custom data as well as building and managing a PowerApp.

On iOS, you have the ability to use the Flow widget in the Notification Center. Unfortunately, if your manually triggered Flow has custom inputs, they're not displayed and your Flow is executed directly, which will likely cause it to fail. Apparently that's an iOS limitation and by-design in Flow, nevertheless a poor experience from the end-user point of view.

So here is why I used Flow in my app. Have you built anything with Flow recently?