Skip to content

Month: November 2018

Azure Functions – Part 6: HTTP and Timer Triggers

Previous Tutorial: Azure Functions – Part 5: Deploying to Azure from VSCode

Two basic and important concepts to understand in Azure Functions are Triggers and Bindings. Triggers are what case the function to execute. Bindings are a simple way to connect data with the function, be it incoming data or outgoing data. Up to now we have created functions that use HTTP triggers (that execute when an HTTP request arrives at the function’s URL), used an HTTP return value for the HTTP response, and Table storage bindings output parameter binding to store a value. In this and the following tutorials I’ll start the investigation more triggers and bindings.

Let’s begin by creating a Function App project from the wizard and in this project create a Function with an HTTP trigger. For the sake of completeness this is what the wizard creates, with some names modified:


using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace Vainolo.AzureFunctionsTutorial.Part6
{
public static class MyFunctions
{
[FunctionName("HttpTrigger")]
public static async Task<IActionResult> HttpTrigger(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
}

view raw

afp6_1.cs

hosted with ❤ by GitHub

Before we continue, some basic stuff:

  • the Azure Functions runtime recognizes a function as any static method in the class that has the FunctionNameannotation.
  • The name of the Azure Function is defined as part of the annotation
  • The name of the method is not important and doesn’t have to be the same as that of the Azure Function.
  • The Function method can be synchronous or asynchronous.
  • An ILogger parameter can be added to the function for logging to the function’s streaming logs.
  • The function can declare parameters that define the trigger of the function, and parameters and return values that are bind to functionality provided by the runtime.

So let’s start digging 🧐.

Every function needs to have a Trigger, otherwise it will exist but will never be invoked, which is not very useful 🥴. The trigger in this function is defined in row 17, with the HttpTrigger annotation. The annotation includes the argument AuthorizationLevel.Anonymous so we can call the function without any authentication, and a list of HTTP methods (get and post).

Just to check what happens, I created a function that does not have a trigger:


[FunctionName("NoTrigger")]
public static void NoTrigger(ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
}

view raw

afp6_2.cs

hosted with ❤ by GitHub

And was glad to see that the build process gives me a warning that the function is missing a trigger. Any help the build system gives is a blessing.

Let’s check another trigger: TimerTrigger. A TimerTrigger, obviously, triggers the function on a schedule. We define this trigger by adding a parameter of type TimerInfo annotated with the TimerTrigger annotation. This annotation receives as parameter either a string formatted as a CRON expression, a string formatted for a TimeSpan, or a type that extends a TimerSchedule. Here’s an example of the first two methods, and as a typical long-time university lecturer, I’ll leave the third one for you to figure out 😊:


// CRON formatted trigger every 5 seconds
[FunctionName("TimerTrigger1")]
public static void TimerTrigger1([TimerTrigger("*/5 * * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"CRON trigger executed at : {DateTime.Now}");
}
[FunctionName("TimerTrigger2")]
public static void TimerTrigger2([TimerTrigger("00:00:03")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"TimeSpan trigger executed at : {DateTime.Now}");
}

view raw

afp6_3.cs

hosted with ❤ by GitHub

Interestingly, the moment I added the TimerTrigger and tried to run the function, it didn’t work. The runtime sait it was missing a value for AzureWebJobsStorage. This seems weird because I don’t see the relationship between a timer and the storage, but a quick search shows that this is by design. Since I’m just playing I decide to set the value of this setting to "Dummy" (in the local.settings.json file), and the Function App starts and output is shown in the console every 3 and 5 just like we defined:

That’s all for today. The full list of triggers available for Azure Functions is located here if you want to investigate them by yourself. For next time I plan to check triggers based on storage like as Blob, Cosmos DB, and Queue (no trigger for Table… I wonder why).  Until then, happy coding!

Next Tutorial: Azure Functions – Part 7: Blob, Queue, and Cosmos DB Triggers