Microsoft Azure Durable Functions Introduction

The runtime of Azure Functions does not maintain the state of any object which created during the execution of the function and you can’t pass the data between functions through regular Azure functions.

By using Azure Durable functions, you can pass data or state between functions. For example, output of one function can pass it as input to other function. Durable Functions billed same as normal Azure functions. Azure Durable Functions supports only C#, F#, and JavaScript languages as of now.

The main components of the durable functions are Activity, Orchestrator, and client.

Activity: These are the main functions that handles actual work. That means, these functions contain actual code which needs to execute. There can be more than one Activity function to execute.

Orchestrator: Orchestrator executes the Activity functions in a specific order to fulfil the actual purpose.

Client: This is the starting point of the Azure Durable function which calls Orchestrator. Instance of Orchestrator can be created using HTTP trigger, Queue trigger, or Timer trigger.

Open Microsoft Visual Studio 2019 => Create new project for Azure Functions and select Empty function template.

Right-click on the project and Add new Azure Function, select Durable Functions Orchestration.

The default code of the Durable Function looks like below.

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
 
namespace AzureDurableExp
{
    public static class DurableFunction
    {
        [FunctionName("DurableFunction")]
        public static async Task<List<string>> RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var outputs = new List<string>();
 
            // Replace "hello" with the name of your Durable Activity Function.
            outputs.Add(await context.CallActivityAsync<string>("DurableFunction_Hello", "Tokyo"));
            outputs.Add(await context.CallActivityAsync<string>("DurableFunction_Hello", "Seattle"));
            outputs.Add(await context.CallActivityAsync<string>("DurableFunction_Hello", "London"));
 
            // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
            return outputs;
        }
 
        [FunctionName("DurableFunction_Hello")]
        public static string SayHello([ActivityTrigger] string name, ILogger log)
        {
            log.LogInformation($"Saying hello to {name}.");
            return $"Hello {name}!";
        }
 
        [FunctionName("DurableFunction_HttpStart")]
        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
            [DurableClient] IDurableOrchestrationClient starter,
            ILogger log)
        {
            // Function input comes from the request content.
            string instanceId = await starter.StartNewAsync("DurableFunction", null);
 
            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
 
            return starter.CreateCheckStatusResponse(req, instanceId);
        }
    }
}

Here SayHello() (function name DurableFunction_Hello) is the Activity, RunOrchestrator() is the Orchestrator, and HttpStart() is the client which calls Orchestrator RunOrchestrator(). Client is using the HttpTrigger to initiate the orchestrator here.

Run the application, copy the Durable Function URL from the window and paste in browser.

Copy the statusQueryGetUri value in the browser which displays our Durable Function result as below.