25 Days of Serverless – Azure Serverless Coding Challenges

Week 1

Whether you’re a seasoned “senior developer” or taking your first steps into development, coding challenges are an excellent way to expand your skillset. Azure Developer Advocates are hosting the 25 days of serverless development challenge and I’m quite intrigued! I’m familiar with foundational concepts for Azure Functions in both C# and Typescript but I can use every opportunity I can get to improve that capability because Azure functions and serverless concepts are no small deal for modern developers. From scalability to ease of deployment to affordability to local development environments… you can’t lose.

Here in Minnesota, we have the potential for sunlight during December from about 7:30am to 4:30pm, which means I have a lot of time in the dark... which leaves me with only a few excuses if I miss a day of the challenge.

Day 1

Day 1 is a REST API endpoint challenge where the endpoint returns the result of a virtual dreidel. Most of my API endpoint experiences with Azure Functions have been in C# and it’s a Sunday so I’m feeling optimistic – this challenge was completed in Typescript: https://github.com/dzsquared/25-days-of-serverless-day1

Getting Started

My local development environment for C# (.Net Core) and Typescript in Azure Functions is already set up through VS Code. If you’re looking to get set up today, follow along with these Microsoft Docs but ignore all of its references to an Azure subscription. You don’t need an Azure subscription to get started and develop locally.

I opened VS Code and used the Azure Function extension to create a new project – TypeScript with the first function populated from the HttpRequest trigger. Everything that follows is modifying that template.

Solving the Challenge

The Dreidel is a 4-sided top/die, so I needed the ability to return a number between 1-4 and created a function below the httpTrigger function in index.ts.

function getDreidelResult():number {
    let dNumber:number = Math.floor(Math.random() * 4) + 1;

    return dNumber;
}

The API is returning the result of a Dreidel spin to the requestor – which I interpreted as needing the symbol and letter/word indicated by that symbol. To establish this object for returning to the user I created a dreidel class.

While the dreidel class is pretty barebones, it contains two pieces that are important to the function:

<p>
  First &#8211; The dreidel class contains two properties, <em>sideSymbol</em> and <em>sideWord.</em> These properties are accessible by the function when the object is manipulated or displayed.
</p>

<p>
  Second &#8211; The dreidel class constructor takes a number parameter and sets the properties based on the incoming number. This constructor allows us to create a <strong>dreidel object</strong> with a randomly generated number between 1and 4.
</p>
export class dreidel {
    public sideSymbol: string;
    public sideWord: string;
constructor(sideArabic: number) {

    switch(sideArabic) {
        case 1: {
            this.sideSymbol = "נ";
            this.sideWord = "Nun";
            break;
        }
        case 2: {
            this.sideSymbol = "ג";
            this.sideWord = "Gimmel";
            break;
        }
        case 3: {
            this.sideSymbol = "ה";
            this.sideWord = "Hay";
            break;
        }
        case 4: {
            this.sideSymbol = "ש";
            this.sideWord = "Shin";
            break;
        }
    }
}

}

From here everything comes together quickly:

  • The dreidel class is added to the index.ts file through an import statement added at the top of the file (line 2).
  • A random number is accessed at line 5 and at line 6 a dreidel object is constructed with that number.
  • The template included a bit of boilerplate code referencing a name variable, which is removed and replaced in the body property at line 11 with dreidelObject.
import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { dreidel } from "./dreidel";

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    let dNumber: number = getDreidelResult();
    let dreidelObject = new dreidel(dNumber);
    console.log("random number generated: "+ dNumber.toString());
    if (dreidelObject) {
        context.res = {
            // status: 200, /* Defaults to 200 */
            body: dreidelObject
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Dreidel spun off table, please try again."
        };
    }
};

export default httpTrigger;



function getDreidelResult():number {
    let dNumber:number = Math.floor(Math.random() * 4) + 1;

    return dNumber;
}

Testing Locally

With VS Code I can test the function from my local machine without deploying to Azure.

<p>
  Going to the <strong>Debug</strong> menu and selecting <strong>Start Debugging</strong>, I am able to troubleshooting and/or monitor the Azure Function <em>just in case it doesn&#8217;t work perfectly the first time.</em>
</p>
best ascii art

VS Code terminal returns the local URL for the function

The easiest method for building with troubleshooting in mind is including console logs in the code (see line 7 of index.ts). This will output to the terminal when the function is called, seen below with “random number generated: 1”

It Works!
Console.log()

Day 2

Day 2’s challenge is a scheduling challenge – and Azure is in the midst of a change to their scheduling offering to Azure Logic Apps. Logic Apps are created through a graphical UI and the result are workflows that can interact with time intervals in 2 potential ways:

The chief difference between those 2 architectures is the ability to dynamically set the schedule in the HTTP trigger to schedule (2nd) option, where the first option runs at a constant interval.

Requested Schedule

The schedule needs to alert a user of several events – but a large portion of the requirements are up for interpretation. Think of this as creating a product for today while balancing the future value of the solution and your ability to deliver it quickly. The ambiguous requirements and my assumptions are below:

<ul>
  <li>
    will Lucy be the only user? <strong>no</strong>
  </li>
  <li>
    how would she like to get notified? <strong>SMS</strong>
  </li>
  <li>
    does she need to be able to start the schedule at any time? <strong>yes</strong>
  </li>
</ul>

Relative schedule compared to 8am:

<ul>
  <li>
    8:00 AM &#8211; start the coffee, set out 4 cups
  </li>
  <li>
    8:25 AM &#8211; pour two cups
  </li>
  <li>
    8:30 AM &#8211; light the candles
  </li>
  <li>
    8:35 AM &#8211; deliver the coffee to Mom and Dad
  </li>
  <li>
    8:39 AM &#8211; return to kitchen, fill two more cups
  </li>
  <li>
    8:40 AM &#8211; relight the candles
  </li>
  <li>
    8:45 AM &#8211; deliver the coffee to Sister and Brother
  </li>
  <li>
    8:49 AM &#8211; return to kitchen, take a break!
  </li>
</ul>

Implement in <30 Minutes

Setup the Twilio Connector
Send an Initial Message, Delay, Repeat

The Logic App is triggered by an HTTP request with 2 properties in the body: startTime (2019-12-13T08:00+0100 in the above example) and contactNumber (a phone number to receive SMS reminders). The remainder of the Logic App is delayed until startTime. The beauty of Logic Apps isn’t really the graphical interface – it’s the prebuilt connectors to many external services, such as Twilio.

By entering a Twilio account ID and access token, you’re ready to create multiple SMS actions in the same Logic App. After each SMS, an additional delay of X number of minutes moves between the items in the schedule. Before you know it, your serverless application is ready to roll.

Additional Notes About Logic Apps

I’d love to hear the nuances that everyone else has learned about Logic Apps – here are a few of my notes from a few years of work with Logic Apps:

  • Built-in connectors may have limitations that the native REST APIs for a service do not – so if a connector for a service, such as Twilio, doesn’t do what you’d like – try using an HTTP request in the Logic App to the service.
  • Logic Apps make excellent wrappers for Azure Functions – it adds the ability to replay HTTP requests easily from the browser.
  • If your Logic App uses nested conditions (IF/ELSE) past a single nesting level – stop. Please, stop. It’s going to get messy quickly and you will regret it. Time to embed an Azure Function in your Logic App.

Day 3 – independent post

Day 4 – independent post

Day 5 – independent post

Day 6 – to be completed at a later date

Day 7