Skip to content

Durable Orchestration

This recipe shows Java Durable Functions with an HTTP starter, orchestrator, and activity function using the Durable Task Java SDK.

Architecture

flowchart TD
    CLIENT[Client] --> STARTER[HTTP starter]
    STARTER --> ORCH[Orchestrator function]
    ORCH --> ACT1[Activity: validate]
    ORCH --> ACT2[Activity: process]
    ORCH --> STATUS[Durable status endpoints]

Prerequisites

Durable extension in host.json:

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "JavaDurableHub"
    }
  }
}

Maven dependencies:

<dependencies>
    <dependency>
        <groupId>com.microsoft.azure.functions</groupId>
        <artifactId>azure-functions-java-library</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-functions-java-library-durabletask</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

Java implementation

package com.contoso.functions;

import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.durabletask.*;
import com.microsoft.durabletask.azurefunctions.*;

import java.util.Optional;

public class DurableFunctions {

    @FunctionName("orchestrationStarter")
    public HttpResponseMessage orchestrationStarter(
        @HttpTrigger(
            name = "request",
            methods = {HttpMethod.POST},
            authLevel = AuthorizationLevel.FUNCTION,
            route = "orchestrators/order"
        ) HttpRequestMessage<Optional<String>> request,
        @DurableClientInput(name = "durableContext") DurableClientContext durableContext
    ) {
        DurableTaskClient client = durableContext.getClient();
        String instanceId = client.scheduleNewOrchestrationInstance("orderOrchestrator", request.getBody().orElse("{}"));
        return durableContext.createCheckStatusResponse(request, instanceId);
    }

    @FunctionName("orderOrchestrator")
    public String orderOrchestrator(
        @DurableOrchestrationTrigger(name = "context") TaskOrchestrationContext context
    ) {
        String payload = context.getInput(String.class);
        String validated = context.callActivity("validateOrder", payload, String.class).await();
        return context.callActivity("processOrder", validated, String.class).await();
    }

    @FunctionName("validateOrder")
    public String validateOrder(
        @DurableActivityTrigger(name = "payload") String payload
    ) {
        return "validated:" + payload;
    }

    @FunctionName("processOrder")
    public String processOrder(
        @DurableActivityTrigger(name = "validatedPayload") String validatedPayload
    ) {
        return "processed:" + validatedPayload;
    }
}

Implementation notes

  • Keep orchestrator code deterministic and move I/O to activity functions.
  • Use createCheckStatusResponse to return status query URLs to callers.
  • Design activities to be retry-safe because orchestration replays can occur.
  • Keep payloads small and store large documents in Blob Storage.

Review Matrix

Review area Page-specific check
Scope Confirm the guidance applies to Durable Orchestration.
Source basis Validate the recommendation against the Microsoft Learn sources in this page.
Evidence Capture command output, portal state, metrics, logs, or screenshots before treating the result as proven.

See Also

Sources