Make Serverless Music – Orchestrate your workflow with Azure [Part 1 – Microsoft Flow]


In this series we take an in-depth look at how you can orchestrate and coordinate processes throughout your system using a variety of offerings on Microsoft's Azure platform. You'll get an overview, pros, cons, and how-tos for each product.

Microsoft Flow stepped on the scene along with a public preview of Microsoft PowerApps back in April, 2016. Primarily targeted at business users, trust me it can be so much more than just a tool to manage to get alerts from Sharepoint or your Inbox 😉

With the same suite of logical operators as Logic Apps (we'll talk more about these later), Flow can if/else, execute in parallel, loop, and retry with the best of them. And best of all, it has a free tier. Here's their current pricing model:

The best news? Everything you're about to see is possible within the Flow Free plan.

Let's get started with a problem statement:
When I receive a request to my Flow, I want to

  1. Validate the schema of the incoming JSON request.
  2. Validate the content of the JSON request against business rules.
  3. Return a response indicating which validations failed and which ones passed.

This seems pretty straightforward and something that might be reasonably common in any business environment. Put it on a /validate endpoint, send requests to it, and you've got a decoupled validation service. So let's see a few ways to skin this cat with Microsoft Flow:

Simple checks done in sequence

Step 1: Define our schema

Let's define our schema as a Person schema like so:

{
    "Name" : {
        "First" : "John",
        "Last" : "Doe",
        "Title" : "Mr"
    },
    "Address" : {
        "Line1" : "1234 Anywhere St.",
        "Line2" : null,
        "City" : "Somewhere",
        "State" : "OR",
        "Zip" : "12345",
        "Country" : "United States of America"
    }
}

For our business rules, we'll enforce:

  1. First & Last name must be present & longer than 1 character
  2. If Address Line 2 is not null, Line 1 must also not be null
  3. City must be present
  4. State must be present & only a 2-letter abbreviation
  5. Zip must be present and 5 characters

And we'll return back a JSON that looks like:

{
    "Errors" : [
        {
            "id" : 1,
            "message" : "First name is empty or less than 1 character"
        },
        { 
            "id" : 3,
            "message" : "Address line 2 is not empty but line 1 is empty"
        },
        ...
    ]
}

Step 2: Make the Flow respond to an HTTP POST request containing a JSON body of a specific schema

This can be done with the HTTP - Request connector:

Upon choosing it, you'll notice something interesting (1):

Once you save your Flow, this area will be populated with the HTTP endpoint for you to hit. Simply copy it (2) and you're off to the races.
For now, we'll use this step in the Flow to perform requirement #1: Validate the JSON schema.

Using the sample input shown prior, we can generate the JSON schema by clicking Use sample payload to generate schema (3) and pasting in the JSON body from above:

After clicking 'Done', you'll see a generated JSON schema show up in the HTTP - Request connector.

You can hand-type the JSON schema, but Flow won't validate that it's correct before Saving. You'll only know if you messed something up at runtime.

Step 3: Prep the return JSON value

Since we'll be executing a sequence of steps and putting the result for each validation in to a body to send back, we need to have a sort of "accumulator" variable. Remember we said ours would be an array. Lucky for us, Flow has just the thing.

Click 'New step' then 'Add an action'

type 'variable' in the search box and choose 'Initialize variable'

Next, name the variable and set it to be an Array type

Now we have an Array in to which we can add output from our validators as they run!

Step 4: Execute our first validation

First & Last name must be present & longer than 1 character

Let's tackle the First name, since this will just repeat for Last name.

Click 'New step' 'Add a condition' now:

Voila, you're met with a condition box, and spots to put both the "if true" and "if false" steps of your choosing. Perfect!
For this check, the condition will simply be len(Name.First) > 1 (in rough pseudocode). Let's knock it out:

Click 'Choose a value' in the Condition box and note what happens. The JSON schema has been used to provide you an "intellisense" of sorts with the properties on the payload that are readily available for inspection. However, we need the length of one of these, not just the property value. So flip over to the 'Expressions' tab and notice what we have under 'Collections':

length() is exactly what we want. Click it. While the cursor is inside the (), flip back over to 'Dynamic content' and choose 'First'. You should end up with something like this:

Click 'OK' and fill out the rest of the condition:

If this fails, we want to append to our output array, so in the 'If no' area of our condition, click 'Add an action'. Type 'variable' in the search, and choose 'Append to array variable'. Add our first failure code:

{ "id" : 1, "message" : "First name is null or less than 2 characters in length" }

Since the rest will just be "rinse, repeat" let's give our Flow a run. Click 'Save' in the upper right and note that you now have a valid URL in our HTTP - Request trigger action at the top:

Heed the warning here! Since we've given a JSON schema to validate against, all requests coming in to our Flow must have Content-Type: application/json in their headers.

Fire up Postman and

  1. Copy your URL in to a new request.
  2. Switch the HTTP Method to POST
  3. Add the Content-Type header
  4. Fill out a raw body with the sample from the start of this post

Before you click 'Send' go to your Flow and click the 'Test' button in the upper right. Choose 'I'll perform the trigger action':

Flow is now waiting for a request to come in so it can show you how it executes through the path. Click 'Send' in Postman. You should be met with something like this back in Flow:

Awesome. It ran, checked the length, found it was > 1 and no-op'd as we expected. Let's set the First Name to null, set Flow to wait for another request (hit Edit, then Test again), and see what happens:

{
    "Name" : {
        "First" : null,
        "Last" : "Doe",
        "Title" : "Mr"
    },
    "Address" : {
        "Line1" : "1234 Anywhere St.",
        "Line2" : null,
        "City" : "Somewhere",
        "State" : "OR",
        "Zip" : "12345",
        "Country" : "United States of America"
    }
}

Ruh roh

Looks like we need to null check before length(). No problem. Click 'Edit' on your Flow, and click the '(+)' that appears above the Condition block when you hover between it and 'Initialize Variable'. Choose 'Add a condition':

This time, for our condition expression we need to check out First JSON property against null. We do this with the equals() expression, like so:

And now we can say if this is true, add an error message, otherwise move on to the other validation. To get 'true' you also must use the 'Expression' panel, just search for 'true'

So let's put our error message add in to the 'If yes' part just like we did the previous one:

but now we want our previous condition (length check) inside the 'false' condition for this check. Easy peasy, simply grab the icon for the length condition, and drag it in to the 'If no' space:

You should now have something that looks like this:

Let's give it another run with that same null input:

HUZZAH!

Now to inspect the outcome. If you click on the 'Append to array variable 2' step, you should see:

So we got a null First name, then we appended on to the array variable a new JSON object definition for the null failure. Sweet.

Now let's do a 1-character first name to watch it go:

{
    "Name" : {
        "First" : "J",
        "Last" : "Doe",
        "Title" : "Mr"
    },
    "Address" : {
        "Line1" : "1234 Anywhere St.",
        "Line2" : null,
        "City" : "Somewhere",
        "State" : "OR",
        "Zip" : "12345",
        "Country" : "United States of America"
    }
}

Perfect! That 2nd error message can now just say "less than 2 characters" but otherwise we're golden!

Now go through and implement the other validations we need.

TIP: You can rename any step in your Flow to be more readable, but only before another step takes a dependency on it. Try this to make your conditions more digestable instead of 'Condition X' all over the place 😉

You should end up with a Flow that looks something like this:

Now for the last part, returning the result to the caller.

Add a new action at the bottom, and search for 'Response'. Click 'See more' and choose 'Request':

Then choose 'Request - Response' and spit out our output variable:

Let's give 'er a run! Using our same request as before we should now get a response in Postman:

[
    {
        "id": 1,
        "message": "First name is null or less than 2 characters in length"
    }
]

PERFECT!

Tweak your request to trigger some/all of the other validations and watch the failures come back.

But, what if we want moar speed?? Let's do it all in parallel (aka Fan out/in pattern)!

Click the '+' under the 'Initialize variable' step and choose 'Add a condition'

Take condition #2 from your list, and drag it above the newly-created parallel condition:

Repeat for the other remaining conditions until you have a Flow that looks like this:

Now we just need to get the 'Response' action to show up after all the parallel executions have completed.
Click 'New step' at the very bottom of the Flow and choose 'Add an action'. With the "Choose an action" dialog open, drag the existing 'Response' object to just below it:

This will create it outside the parallel executions. You can click 'Cancel' on the "Choose an action" dialog now.

Give our Flow an execution, and you'll see the validations are processed in parallel and can show up in our resulting array object in any order, depending on who completed execution first.

You can rename your Flow to something more intuitive by simply clicking its given name in the upper-left corner while editing


Hopefully you've found this an interesting foray in to the power of serverless computing and Microsoft's business-class serverless offering, Flow. It's certainly more powerful than it's given credit for (in my mind)!

At this point you're probably wondering "Ok so... what can't I use Flow for?" or "When shouldn't I use this tool, it's awesome!". Here's the thing, Flow is intended for business users to be used in a self-service manner. You can't do any of the more advanced business workflow operations like use an Integration Account to read schemas, etc with Flow. Also, as I showed earlier, Flow's fastest checks are at 1-minute intervals. This may not be adequate for higher-priority business operations. You only get the in-browser editor and as a result the ALM story is much more limited (test, prod only). From the administration side, Flow offers only DLP & licensing controls as well as O365 Sec & Compliance logs and DLP.

If you want to take Flow to the next level, stay tuned for next time when I show how to do the same process using Flow's IT Pro-grade offering: Logic Apps. More detail between these two can be found here.

Comments (0)

Skip to main content