Create your first durable function in JavaScript

Durable Functions is an extension of Azure Functions that lets you write stateful functions in a serverless environment. The extension manages state, checkpoints, and restarts for you.

In this article, you learn how to use the Visual Studio Code Azure Functions extension to locally create and test a "hello world" durable function. This function will orchestrate and chain together calls to other functions. You then publish the function code to Azure.

Running durable function in Azure

Prerequisites

To complete this tutorial:

If you don't have an Azure subscription, create a free account before you begin.

Install the Azure Function extension

The Azure Functions extension is used to create, test, and deploy functions to Azure.

  1. In Visual Studio Code, open Extensions and search for azure functions, or open this link in Visual Studio Code.

  2. Select Install to install the extension to Visual Studio Code.

    Install the extension for Azure Functions

  3. Restart Visual Studio Code and select the Azure icon on the Activity bar. You should see an Azure Functions area in the Side Bar.

    Azure Functions area in the Side Bar

Create an Azure Functions project

The Azure Functions project template in Visual Studio Code creates a project that can be published to a function app in Azure. A function app lets you group functions as a logical unit for management, deployment, and sharing of resources.

  1. In Visual Studio Code, select the Azure logo to display the Azure: Functions area, and then select the Create New Project icon.

    Create a function app project

  2. Choose a location for your project workspace and choose Select.

    Note

    This article was designed to be completed outside of a workspace. In this case, do not select a project folder that is part of a workspace.

  3. Select the language for your function app project. In this article, JavaScript is used. Choose project language

  4. When prompted, choose Add to workspace.

Visual Studio Code creates the function app project in a new workspace. This project contains the host.json and local.settings.json configuration files, plus any language-specific project files. You also get a new Git repository in the project folder.

Install the Durable Functions npm package

  1. Install the durable-functions npm package by running npm install durable-functions in the root directory of the function app.

Create a Starter Function

First, create an HTTP triggered function that starts a durable function orchestration.

  1. From Azure: Functions, choose the Create Function icon.

    Create a function

  2. Select the folder with your function app project and select the HTTP trigger function template.

    Choose the HTTP trigger template

  3. Type HttpStart for the function name and press Enter, then select Anonymous authentication.

    Choose anonymous authentication

    A function is created in your chosen language using the template for an HTTP-triggered function.

  4. Replace index.js with the below JavaScript:

    const df = require("durable-functions");
    
    module.exports = async function (context, req) {
        const client = df.getClient(context);
        const instanceId = await client.startNew(req.params.functionName, undefined, req.body);
    
        context.log(`Started orchestration with ID = '${instanceId}'.`);
    
        return client.createCheckStatusResponse(context.bindingData.req, instanceId);
    };
    
  5. Replace function.json with the below JSON:

    {
      "bindings": [
        {
          "authLevel": "anonymous",
          "name": "req",
          "type": "httpTrigger",
          "direction": "in",
          "route": "orchestrators/{functionName}",
          "methods": ["get", "post"]
        },
        {
          "name": "$return",
          "type": "http",
          "direction": "out"
        },
        {
          "name": "starter",
          "type": "orchestrationClient",
          "direction": "in"
        }
      ]
    }
    

We've now created an entry-point into our Durable Function. Let's add an orchestrator.

Create an Orchestrator Function

Next, you create another function to be the orchestrator. We use the HTTP trigger function template for convenience. The function code itself is replaced by the orchestrator code.

  1. Repeat the steps from the previous section to create a second function using the HTTP trigger template. This time name the function OrchestratorFunction.

  2. Open the index.js file for the new function and replace the contents with the following code:

    const df = require("durable-functions");
    
    module.exports = df.orchestrator(function*(context){
        context.log("Starting chain sample");
        const output = [];
        output.push(yield context.df.callActivity("E1_SayHello", "Tokyo"));
        output.push(yield context.df.callActivity("E1_SayHello", "Seattle"));
        output.push(yield context.df.callActivity("E1_SayHello", "London"));
    
        return output;
    });
    
  3. Open the function.json file and replace it with the following JSON:

    {
      "bindings": [
        {
          "name": "context",
          "type": "orchestrationTrigger",
          "direction": "in"
        }
      ]
    }
    

We've added an orchestrator to coordinate activity functions. Let's now add the referenced activity function.

Create an Activity Function

  1. Repeat the steps from the previous sections to create a third function using the HTTP trigger template. But this time name the function E1_SayHello.

  2. Open the index.js file for the new function and replace the contents with the following code:

    module.exports = async function(context) {
        return `Hello ${context.bindings.name}!`;
    };
    
  3. Replace function.json with the below JSON:

    {
      "bindings": [
        {
          "name": "name",
          "type": "activityTrigger",
          "direction": "in"
        }
      ]
    }
    

We've now added all components needed to start off an orchestration and chain together activity functions.

Test the function locally

Azure Functions Core Tools lets you run an Azure Functions project on your local development computer. You're prompted to install these tools the first time you start a function from Visual Studio Code.

  1. On a Windows computer, start the Azure Storage Emulator and make sure that the AzureWebJobsStorage property of local.settings.json is set to UseDevelopmentStorage=true.

    For Storage Emulator 5.8 make sure that the AzureWebJobsSecretStorageType property of local.settings.json is set to files. On a Mac or Linux computer, you must set the AzureWebJobsStorage property to the connection string of an existing Azure storage account. You create a storage account later in this article.

  2. To test your function, set a breakpoint in the function code and press F5 to start the function app project. Output from Core Tools is displayed in the Terminal panel. If this is your first time using Durable Functions, the Durable Functions extension is installed and the build might take a few seconds.

    Note

    JavaScript Durable Functions require version 1.7.0 or greater of the Microsoft.Azure.WebJobs.Extensions.DurableTask extension. Run the following command from the root folder of your Azure Functions app to install the Durable Functions extension func extensions install -p Microsoft.Azure.WebJobs.Extensions.DurableTask -v 1.7.0

  3. In the Terminal panel, copy the URL endpoint of your HTTP-triggered function.

    Azure local output

  4. Replace {functionName} with OrchestratorFunction.

  5. Using a tool like Postman or cURL, send a HTTP POST request to the URL endpoint.

    The response is the initial result from the HTTP function letting us know the durable orchestration has started successfully. It is not yet the end result of the orchestration. The response includes a few useful URLs. For now, let's query the status of the orchestration.

  6. Copy the URL value for statusQueryGetUri and paste it in the browser's address bar and execute the request. Alternatively you can also continue to use Postman to issue the GET request.

    The request will query the orchestration instance for the status. You should get an eventual response which shows us the instance has completed, and includes the outputs or results of the durable function. It looks like:

    {
        "instanceId": "d495cb0ac10d4e13b22729c37e335190",
        "runtimeStatus": "Completed",
        "input": null,
        "customStatus": null,
        "output": [
            "Hello Tokyo!",
            "Hello Seattle!",
            "Hello London!"
        ],
        "createdTime": "2018-11-08T07:07:40Z",
        "lastUpdatedTime": "2018-11-08T07:07:52Z"
    }
    
  7. To stop debugging, press Shift + F5 in VS Code.

After you've verified that the function runs correctly on your local computer, it's time to publish the project to Azure.

Sign in to Azure

Before you can publish your app, you must sign in to Azure.

  1. In the Azure: Functions area, choose Sign in to Azure.... If you don't already have one, you can Create a free Azure account.

    Function localhost response in the browser

  2. When prompted, select Copy & Open, or copy the displayed code and open https://aka.ms/devicelogin in your browser.

  3. Paste the copied code in the Device Login page, verify the sign in for Visual Studio Code, then select Continue.

  4. Complete the sign in using your Azure account credentials. After you have successfully signed in, you can close the browser.

Publish the project to Azure

Visual Studio Code lets you publish your functions project directly to Azure. In the process, you create a function app and related resources in your Azure subscription. The function app provides an execution context for your functions. The project is packaged and deployed to the new function app in your Azure subscription.

This article assumes that you are creating a new function app.

Important

Publishing to an existing function app overwrites the content of that app in Azure.

  1. In the Azure: Functions area, select the Deploy to Function App icon.

    Function app settings

  2. If not signed-in, you are prompted to Sign in to Azure. You can also Create a free Azure account. After successful sign in from the browser, go back to Visual Studio Code.

  3. If you have multiple subscriptions, Select a subscription for the function app, then choose + Create New Function App in Azure.

  4. Type a globally unique name that identifies your function app and press Enter. Valid characters for a function app name are a-z, 0-9, and -.

  5. Choose + Create New Resource Group, type a resource group name, like myResourceGroup, and press enter. You can also use an existing resource group.

  6. Choose + Create New Storage Account, type a globally unique name of the new storage account used by your function app and press Enter. Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only. You can also use an existing account.

  7. Choose a location in a region near you or near other services your functions access.

    When you press Enter, the following Azure resources are created in your subscription:

    • Resource group: Contains all of the created Azure resources. The name is based on your function app name.
    • Storage account: A standard Storage account is created with a unique name that is based on your function app name.
    • Hosting plan: A consumption plan is created in the West US region to host your serverless function app.
    • Function app: Your project is deployed to and runs in this new function app.

    A notification is displayed after your function app is created and the deployment package is applied. Select View Output in this notification to view the creation and deployment results, including the Azure resources that you created.

  8. Back in the Azure: Functions area, expand the new function app under your subscription. Expand Functions, right-click HttpTrigger, and then choose Copy function URL.

    Copy the function URL for the new HTTP trigger

Test your function in Azure

  1. Copy the URL of the HTTP trigger from the Output panel. The URL that calls your HTTP-triggered function should be in the following format:

     http://<functionappname>.azurewebsites.net/orchestrators/<functionname>
    
  2. Paste this new URL for the HTTP request into your browser's address bar. You should get the same status response as before when using the published app.

Next steps

You have used Visual Studio Code to create and publish a JavaScript durable function app.