Practical ASP.NET

Serverless C# with Azure Functions: HTTP-Triggered Functions

Last time I looked at the basics of triggers. Let's look at creating an HTTP-triggered function for displaying a greeting based on a target audience.

The last time we looked at Azure Functions, I introduced you to the basic triggers you can use with them. There are a number of events that can cause functions to begin execution ("triggered"), one of which is in response to an HTTP request. These HTTP-triggered functions could, for example, perform CRUD operations for a single-page Web app or mobile front-end. That's what I'll look at this time.

HTTP-triggered functions have a number of capabilities. They can be authorized by keys that calling clients need to provide, they can be limited to specific HTTP verbs (such as POST, GET and so on), they can return data to the calling client, and they can receive request data via query string parameters, request body data or URL route templates. Like other functions they can also integrate with other Azure services such as Blob Storage, Event Hubs, queues and so on.

Creating a HTTP-Triggered Function
To create a new HTTP-triggered function, open an existing Function App in the Azure Portal or create a new one.

Click the New Function button, choose C# from the language dropdown box, and select the HTTPTrigger-CSharp template (see Figure 1). Give the function a name, for example "GenerateGreetingForAge," and choose Anonymous for the Authorization level (see Figure 2). Note that this will allow anyone to call the function via HTTP an unrestricted number of times, so you would normally want to restrict access by key. Finally, click the "create" button to add the new function to the Function App.

[Click on image for larger view.] Figure 1. Creating a New HTTP Trigger Function
[Click on image for larger view.] Figure 2. Choosing a Function Name and Authorization Level

A new function will now be created and the code editor will be loaded (see Figure 3). At the top of the editor window is the URL of the function; for example, "https://vsmdemos.azurewebsites.net/api/GenerateGreetingForAge." The template adds some starter sample code that allows a name to be passed to the function and returned to the client prefixed with "Hello."

[Click on image for larger view.] Figure 3. Function Code Editor

This GenerateGreetingForAge function is going to examine the age that’s passed to it (as a querystring parameter) and return an appropriate greeting tailored to the target age group. The code in Listing 1 shows an example of this.

Listing 1: Custom Code in a HTTP Trigger Function
using System.Net;

public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log)
{
  log.Info("C# HTTP trigger function processed a request.");

  // Parse query parameter
  string age = req.GetQueryNameValuePairs()
    .FirstOrDefault(q => string.Compare(q.Key, "age", true) == 0)
    .Value;

  if (string.IsNullOrWhiteSpace(age))
  {
    var errorResponse = req.CreateResponse(HttpStatusCode.BadRequest, 
                                          "Please pass an age on the query string"); 
    return errorResponse;
  }

  string greeting = GenerateGreeting(int.Parse(age));

  var greetingResponse = req.CreateResponse(HttpStatusCode.OK, greeting); 
    
  return greetingResponse;
}

public static string GenerateGreeting(int age)
{    
  if (age < 18) return "Yo what's up";
  if (age < 30) return "Hey there";
  if (age < 50) return "Hi";
    
  return "Greetings";    
}

Calling the function with the URL https://vsmdemos.azurewebsites.net/api/GenerateGreetingForAge?age=50 would result in "Greetings" being returned to the caller.

The URL https://vsmdemos.azurewebsites.net/api/GenerateGreetingForAge?age=15 would result in "Yo what's up" being returned.

Configuring Route Templates
Route templates allow the customization of the function’s URL and also allow the mapping of input data from the URL into the function. For example, adding a route template of "greeting/{age}" would change the calling URL from https://vsmdemos.azurewebsites.net/api/GenerateGreetingForAge?age=15 to https://vsmdemos.azurewebsites.net/api/greeting/15.

The "{age}" part of the route template now maps to an additional parameter in the Run method as Listing 2 shows.

Listing 2: Route Template Data Mapped to a Parameter Called Name
using System.Net;

public static HttpResponseMessage Run(HttpRequestMessage req, int age, TraceWriter log)
{
  log.Info("C# HTTP trigger function processed a request.");

  string greeting = GenerateGreeting(age);

  var greetingResponse = req.CreateResponse(HttpStatusCode.OK, greeting); 
    
  return greetingResponse;
}

public static string GenerateGreeting(int age)
{    
  if (age < 18) return "Yo what's up";
  if (age < 30) return "Hey there";
  if (age < 50) return "Hi";
    
  return "Greetings";    
}

Function Authorization
To authorize use, the function authorization level can be changed from Anonymous to either Function or Admin. Doing so will require the client to provide the correct key either as a querystring parameter called code or in an HTTP header called x-functions-key. Changing the authorization level to function changes the URL to https://vsmdemos.azurewebsites.net/api/greeting/15?code=wD6ca3BKsQlaCGTsCf7lpfVaRup1FJXm9C0Aqhl5PLL8I8VBsfojEQ==. Providing an incorrect or missing code querystring parameter results in a 401 Unauthorized response code.

To learn more about Azure Functions, check out the documentation here and the series of articles on my blog here.

About the Author

Jason Roberts is a Microsoft C# MVP with over 15 years experience. He writes a blog at http://dontcodetired.com, has produced numerous Pluralsight courses, and can be found on Twitter as @robertsjason.

comments powered by Disqus

Featured

Subscribe on YouTube