HTTP-funktioner

Durable Functions har flera funktioner som gör det enkelt att införliva hållbara orkestreringar och entiteter i HTTP-arbetsflöden. Den här artikeln beskriver några av dessa funktioner.

Exponera HTTP-API:er

Orkestreringar och entiteter kan anropas och hanteras med HTTP-begäranden. Durable Functions-tillägget exponerar inbyggda HTTP-API:er. Den innehåller även API:er för att interagera med orkestreringar och entiteter inifrån HTTP-utlösta funktioner.

Inbyggda HTTP-API:er

Durable Functions-tillägget lägger automatiskt till en uppsättning HTTP-API:er till Azure Functions-värden. Med dessa API:er kan du interagera med och hantera orkestreringar och entiteter utan att skriva någon kod.

Följande inbyggda HTTP-API:er stöds.

I artikeln HTTP-API:er finns en fullständig beskrivning av alla inbyggda HTTP-API:er som exponeras av Durable Functions-tillägget.

HTTP API URL-identifiering

Orchestration-klientbindningen exponerar API:er som kan generera praktiska HTTP-svarsnyttolaster. Den kan till exempel skapa ett svar som innehåller länkar till hanterings-API:er för en specifik orkestreringsinstans. I följande exempel visas en HTTP-utlösarfunktion som visar hur du använder det här API:et för en ny orkestreringsinstans:

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

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.Extensions.Logging;

namespace VSSample
{
    public static class HttpStart
    {
        [FunctionName("HttpStart")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
            [DurableClient] IDurableClient starter,
            string functionName,
            ILogger log)
        {
            // Function input comes from the request content.
            object eventData = await req.Content.ReadAsAsync<object>();
            string instanceId = await starter.StartNewAsync(functionName, eventData);

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

            return starter.CreateCheckStatusResponse(req, instanceId);
        }
    }
}

Det går att starta en orchestrator-funktion med hjälp av de HTTP-utlösarfunktioner som visades tidigare med hjälp av valfri HTTP-klient. Följande cURL-kommando startar en orchestrator-funktion med namnet DoWork:

curl -X POST https://localhost:7071/orchestrators/DoWork -H "Content-Length: 0" -i

Nästa är ett exempelsvar för en orkestrering som har abc123 som sitt ID. Viss information har tagits bort för tydlighetens skull.

HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Location: http://localhost:7071/runtime/webhooks/durabletask/instances/abc123?code=XXX
Retry-After: 10

{
    "id": "abc123",
    "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123?code=XXX",
    "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123/raiseEvent/{eventName}?code=XXX",
    "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123?code=XXX",
    "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/abc123/terminate?reason={text}&code=XXX"
}

I föregående exempel motsvarar vart och ett av fälten som slutar i Uri ett inbyggt HTTP-API. Du kan använda dessa API:er för att hantera målorkestreringsinstansen.

Kommentar

Formatet på webhook-URL:erna beror på vilken version av Azure Functions-värden du kör. Föregående exempel är för Azure Functions 2.0-värden.

En beskrivning av alla inbyggda HTTP-API:er finns i HTTP API-referensen.

Asynkron åtgärdsspårning

HTTP-svaret som nämnts tidigare är utformat för att implementera långvariga HTTP-asynkrona API:er med Durable Functions. Det här mönstret kallas ibland för konsumentmönstret för avsökning. Klient-/serverflödet fungerar på följande sätt:

  1. Klienten utfärdar en HTTP-begäran för att starta en tidskrävande process som en orkestreringsfunktion.
  2. HTTP-målutlösaren returnerar ett HTTP 202-svar med ett platshuvud som har värdet "statusQueryGetUri".
  3. Klienten avsöker URL:en i platsrubriken. Klienten fortsätter att se HTTP 202-svar med en platsrubrik.
  4. När instansen är klar eller misslyckas returnerar slutpunkten i platshuvudet HTTP 200.

Det här protokollet tillåter samordning av långvariga processer med externa klienter eller tjänster som kan avsöka en HTTP-slutpunkt och följa platsrubriken. Både klient- och serverimplementeringarna för det här mönstret är inbyggda i HTTP-API:erna för Durable Functions.

Kommentar

Som standard stöder alla HTTP-baserade åtgärder som tillhandahålls av Azure Logic Apps standardmönstret för asynkrona åtgärder. Den här funktionen gör det möjligt att bädda in en långvarig varaktig funktion som en del av ett Logic Apps-arbetsflöde. Du hittar mer information om Logic Apps-stöd för asynkrona HTTP-mönster i dokumentationen om Azure Logic Apps-arbetsflöden och utlösare.

Kommentar

Interaktioner med orkestreringar kan göras från valfri funktionstyp, inte bara HTTP-utlösta funktioner.

Mer information om hur du hanterar orkestreringar och entiteter med hjälp av klient-API:er finns i artikeln Instanshantering.

Använda HTTP-API:er

Enligt beskrivningen i kodbegränsningarna för orchestrator-funktionen kan orkestreringsfunktioner inte göra I/O direkt. I stället anropar de vanligtvis aktivitetsfunktioner som utför I/O-åtgärder.

Från och med Durable Functions 2.0 kan orkestreringar använda HTTP-API:er internt med hjälp av orkestreringsutlösarbindningen.

I följande exempelkod visas en orchestrator-funktion som gör en utgående HTTP-begäran:

[FunctionName("CheckSiteAvailable")]
public static async Task CheckSiteAvailable(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Uri url = context.GetInput<Uri>();

    // Makes an HTTP GET request to the specified endpoint
    DurableHttpResponse response = 
        await context.CallHttpAsync(HttpMethod.Get, url);

    if (response.StatusCode >= 400)
    {
        // handling of error codes goes here
    }
}

Genom att använda åtgärden "anropa HTTP" kan du utföra följande åtgärder i orkestreringsfunktionerna:

  • Anropa HTTP-API:er direkt från orkestreringsfunktioner, med vissa begränsningar som nämns senare.
  • Stöder automatiskt http 202-statussökningsmönster på klientsidan.
  • Använd Azure Managed Identities för att göra auktoriserade HTTP-anrop till andra Azure-slutpunkter.

Möjligheten att använda HTTP-API:er direkt från orchestrator-funktioner är avsedd som en bekvämlighet för en viss uppsättning vanliga scenarier. Du kan implementera alla dessa funktioner själv med hjälp av aktivitetsfunktioner. I många fall kan aktivitetsfunktioner ge dig mer flexibilitet.

HTTP 202-hantering

API:et "anropa HTTP" kan automatiskt implementera klientsidan av avsökningskonsumentmönstret. Om ett kallat API returnerar ett HTTP 202-svar med en platsrubrik, avsöker orchestrator-funktionen automatiskt platsresursen tills du får ett annat svar än 202. Det här svaret är svaret som returneras till orchestrator-funktionskoden.

Kommentar

  1. Orchestrator-funktioner har också inbyggt stöd för konsumentmönstret för avsökning på serversidan, enligt beskrivningen i Async-åtgärdsspårning. Det här stödet innebär att orkestreringar i en funktionsapp enkelt kan samordna orkestreringsfunktionerna i andra funktionsappar. Detta liknar underorkestreringskonceptet , men med stöd för kommunikation mellan appar. Det här stödet är särskilt användbart för utveckling av appar i mikrotjänststil.
  2. På grund av en tillfällig begränsning är det inbyggda HTTP-avsökningsmönstret för närvarande inte tillgängligt i JavaScript/TypeScript och Python.

Hanterade identiteter

Durable Functions stöder inbyggt anrop till API:er som godkänner Microsoft Entra-token för auktorisering. Det här stödet använder Azure-hanterade identiteter för att hämta dessa token.

Följande kod är ett exempel på en orchestrator-funktion. Funktionen gör autentiserade anrop för att starta om en virtuell dator med hjälp av REST-API:et för virtuella Azure Resource Manager-datorer.

[FunctionName("RestartVm")]
public static async Task RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string subscriptionId = "mySubId";
    string resourceGroup = "myRG";
    string vmName = "myVM";
    string apiVersion = "2019-03-01";
    
    // Automatically fetches an Azure AD token for resource = https://management.core.windows.net/.default
    // and attaches it to the outgoing Azure Resource Manager API call.
    var restartRequest = new DurableHttpRequest(
        HttpMethod.Post, 
        new Uri($"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines/{vmName}/restart?api-version={apiVersion}"),
        tokenSource: new ManagedIdentityTokenSource("https://management.core.windows.net/.default"));
    DurableHttpResponse restartResponse = await context.CallHttpAsync(restartRequest);
    if (restartResponse.StatusCode != HttpStatusCode.OK)
    {
        throw new ArgumentException($"Failed to restart VM: {restartResponse.StatusCode}: {restartResponse.Content}");
    }
}

I föregående exempel konfigureras parametern tokenSource för att hämta Microsoft Entra-token för Azure Resource Manager. Token identifieras av resurs-URI: https://management.core.windows.net/.defaultn . Exemplet förutsätter att den aktuella funktionsappen antingen körs lokalt eller har distribuerats som en funktionsapp med en hanterad identitet. Den lokala identiteten eller den hanterade identiteten antas ha behörighet att hantera virtuella datorer i den angivna resursgruppen myRG.

Vid körning returnerar den konfigurerade tokenkällan automatiskt en OAuth 2.0-åtkomsttoken. Källan lägger sedan till token som en ägartoken i auktoriseringshuvudet för den utgående begäran. Den här modellen är en förbättring jämfört med att manuellt lägga till auktoriseringshuvuden i HTTP-begäranden av följande skäl:

  • Tokenuppdateringen hanteras automatiskt. Du behöver inte oroa dig för förfallna token.
  • Token lagras aldrig i ett varaktigt orkestreringstillstånd.
  • Du behöver inte skriva någon kod för att hantera tokenförvärv.

Du hittar ett mer komplett exempel i det förkompilerade exemplet C# RestartVMs.

Hanterade identiteter är inte begränsade till Azure-resurshantering. Du kan använda hanterade identiteter för att komma åt alla API:er som accepterar Microsoft Entra-ägartoken, inklusive Azure-tjänster från Microsoft och webbappar från partner. En partners webbapp kan till och med vara en annan funktionsapp. En lista över Azure-tjänster från Microsoft som stöder autentisering med Microsoft Entra-ID finns i Azure-tjänster som stöder Microsoft Entra-autentisering.

Begränsningar

Det inbyggda stödet för att anropa HTTP-API:er är en bekvämlighetsfunktion. Det är inte lämpligt för alla scenarier.

HTTP-begäranden som skickas av orchestrator-funktioner och deras svar serialiseras och sparas som meddelanden i Durable Functions-lagringsprovidern. Det här beständiga köbeteendet säkerställer att HTTP-anrop är tillförlitliga och säkra för orkestreringsrepris. Det beständiga köbeteendet har dock också begränsningar:

  • Varje HTTP-begäran innebär ytterligare svarstider jämfört med en intern HTTP-klient.
  • Beroende på den konfigurerade lagringsprovidern kan stora begäran- eller svarsmeddelanden avsevärt försämra orkestreringsprestandan. När du till exempel använder Azure Storage komprimeras OCH lagras HTTP-nyttolaster som är för stora för att få plats i Azure Queue-meddelanden i Azure Blob Storage.
  • Direktuppspelning, segmenterade och binära nyttolaster stöds inte.
  • Möjligheten att anpassa HTTP-klientens beteende är begränsad.

Om någon av dessa begränsningar kan påverka ditt användningsfall bör du i stället överväga att använda aktivitetsfunktioner och språkspecifika HTTP-klientbibliotek för att göra utgående HTTP-anrop.

Kommentar

Om du är .NET-utvecklare kanske du undrar varför den här funktionen använder typerna DurableHttpRequest och DurableHttpResponse i stället för de inbyggda .NET HttpRequestMessage- och HttpResponseMessage-typerna.

Det här designvalet är avsiktligt. Den främsta orsaken är att anpassade typer hjälper till att säkerställa att användarna inte gör felaktiga antaganden om de beteenden som stöds för den interna HTTP-klienten. Typer som är specifika för Durable Functions gör det också möjligt att förenkla API-designen. De kan också göra det enklare att göra särskilda funktioner tillgängliga, till exempel integrering av hanterad identitet och konsumentmönstret för avsökning.

Utökningsbarhet (endast.NET)

Det är möjligt att anpassa beteendet för orkestreringens interna HTTP-klient med hjälp av Azure Functions .NET-beroendeinmatning. Den här möjligheten kan vara användbar för att göra små beteendeändringar. Det kan också vara användbart för enhetstestning av HTTP-klienten genom att mata in falska objekt.

I följande exempel visas hur du använder beroendeinmatning för att inaktivera TLS/SSL-certifikatverifiering för orkestreringsfunktioner som anropar externa HTTP-slutpunkter.

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        // Register own factory
        builder.Services.AddSingleton<
            IDurableHttpMessageHandlerFactory,
            MyDurableHttpMessageHandlerFactory>();
    }
}

public class MyDurableHttpMessageHandlerFactory : IDurableHttpMessageHandlerFactory
{
    public HttpMessageHandler CreateHttpMessageHandler()
    {
        // Disable TLS/SSL certificate validation (not recommended in production!)
        return new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback =
                HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
        };
    }
}

Nästa steg