Creating Your First Durable Function

Introduction

In this section, you’ll learn how to scaffold and run a basic Azure Durable Function project using .NET and Visual Studio Code. You’ll create three essential functions: an orchestrator, an activity, and an HTTP starter. These templates are provided by the Azure Functions Core Tools.

Let’s walk through the steps to create a basic Azure Durable Function using Visual Studio Code and .NET:

1. Initialize a New Project

func init MyDurableApp --worker-runtime dotnet
cd MyDurableApp

2. Create the Orchestrator Function

func new --name HelloOrchestrator --template "Durable Functions Orchestration"

This function coordinates the workflow. Here is the default generated code:

[FunctionName("HelloOrchestrator")]
public static async Task<List<string>> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "London"));

    return outputs;
}

3. Create an Activity Function

func new --name SayHello --template "Durable Functions Activity"

This function performs the work requested by the orchestrator. The generated template code looks like this:

[FunctionName("SayHello")]
public static string SayHello([ActivityTrigger] string name, ILogger log)
{
    log.LogInformation($"Saying hello to {name}.");
    return $"Hello, {name}!";
}

4. Update the Orchestrator to Call the Activity

(Already shown above)

5. Create the HTTP Starter Function

func new --name HttpStart --template "Durable Functions HTTP Starter"

This function triggers the orchestration using an HTTP call. Here’s the default template:

[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient starter,
    ILogger log)
{
    // Function input comes from the request content.
    string instanceId = await starter.StartNewAsync("HelloOrchestrator", null);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    return starter.CreateCheckStatusResponse(req, instanceId);
}

6. Run Locally and Test

func start
  • Navigate to the local URL printed in your terminal.
  • You’ll receive an orchestration status URL where you can check the progress and results.

Reflection Questions

  1. What are the responsibilities of each function type in Durable Functions (client, orchestrator, activity)?
  2. How does the Durable Task Framework assist in managing workflow state?
  3. Why might you choose Durable Functions over Logic Apps or traditional Azure Functions?
  4. What would happen if one of the activity functions failed—how is error handling typically managed?
  5. How does local development with Azurite simulate Azure Storage behavior?