HTTP-functies

Durable Functions heeft verschillende functies waarmee u eenvoudig duurzame indelingen en entiteiten kunt opnemen in HTTP-werkstromen. In dit artikel wordt dieper ingegaan op een aantal van deze functies.

HTTP-API's beschikbaar maken

Indelingen en entiteiten kunnen worden aangeroepen en beheerd met behulp van HTTP-aanvragen. De Durable Functions-extensie maakt ingebouwde HTTP-API's beschikbaar. Het biedt ook API's voor interactie met indelingen en entiteiten vanuit door HTTP geactiveerde functies.

Ingebouwde HTTP-API's

De Durable Functions-extensie voegt automatisch een set HTTP-API's toe aan de Azure Functions-host. Met deze API's kunt u communiceren met en beheren van indelingen en entiteiten zonder code te schrijven.

De volgende ingebouwde HTTP-API's worden ondersteund.

Zie het artikel http-API's voor een volledige beschrijving van alle ingebouwde HTTP-API's die worden weergegeven door de Durable Functions-extensie.

HTTP API-URL-detectie

De orchestration-clientbinding maakt API's beschikbaar die handige HTTP-antwoordpayloads kunnen genereren. Het kan bijvoorbeeld een antwoord maken met koppelingen naar beheer-API's voor een specifieke indelingsinstantie. In de volgende voorbeelden ziet u een HTTP-triggerfunctie die laat zien hoe u deze API gebruikt voor een nieuw indelingsexemplaar:

// 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);
        }
    }
}

Het starten van een orchestratorfunctie met behulp van de eerder weergegeven HTTP-triggerfuncties kan worden uitgevoerd met behulp van elke HTTP-client. Met de volgende cURL-opdracht wordt een orchestratorfunctie gestart met de naam DoWork:

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

Hierna volgt een voorbeeldantwoord voor een indeling die de id heeft abc123 . Sommige details zijn voor duidelijkheid verwijderd.

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"
}

In het vorige voorbeeld komt elk van de velden die eindigen Uri overeen met een ingebouwde HTTP-API. U kunt deze API's gebruiken om het doelindelingexemplaar te beheren.

Notitie

De indeling van de webhook-URL's is afhankelijk van de versie van de Azure Functions-host die u uitvoert. Het vorige voorbeeld is voor de Azure Functions 2.0-host.

Zie de HTTP-API-verwijzing voor een beschrijving van alle ingebouwde HTTP-API's.

Asynchrone bewerking bijhouden

Het eerder genoemde HTTP-antwoord is ontworpen voor het implementeren van langlopende HTTP asynchrone API's met Durable Functions. Dit patroon wordt soms het polling consumer-patroon genoemd. De client-/serverstroom werkt als volgt:

  1. De client geeft een HTTP-aanvraag uit om een langlopend proces te starten, zoals een orchestratorfunctie.
  2. De HTTP-doeltrigger retourneert een HTTP 202-antwoord met een locatieheader met de waarde statusQueryGetUri.
  3. De client peilt de URL in de locatieheader. De client blijft HTTP 202-antwoorden zien met een locatieheader.
  4. Wanneer het exemplaar is voltooid of mislukt, retourneert het eindpunt in de locatieheader HTTP 200.

Met dit protocol kunt u langlopende processen coördineren met externe clients of services die een HTTP-eindpunt kunnen peilen en de locatieheader kunnen volgen. Zowel de client- als serverimplementaties van dit patroon zijn ingebouwd in de HTTP-API's van Durable Functions.

Notitie

Standaard ondersteunen alle HTTP-acties van Azure Logic Apps het standaard asynchrone bewerkingspatroon. Met deze mogelijkheid kunt u een langlopende duurzame functie insluiten als onderdeel van een Logic Apps-werkstroom. Meer informatie over Logic Apps-ondersteuning voor asynchrone HTTP-patronen vindt u in de azure Logic Apps-werkstroomacties en triggersdocumentatie.

Notitie

Interacties met indelingen kunnen worden uitgevoerd vanuit elk functietype, niet alleen door HTTP geactiveerde functies.

Zie het artikel Exemplaarbeheer voor meer informatie over het beheren van indelingen en entiteiten met behulp van client-API's.

HTTP-API's gebruiken

Zoals beschreven in de codebeperkingen van de orchestratorfunctie, kunnen orchestratorfuncties I/O niet rechtstreeks uitvoeren. In plaats daarvan roepen ze doorgaans activiteitsfuncties aan die I/O-bewerkingen uitvoeren.

Vanaf Durable Functions 2.0 kunnen orchestrations systeemeigen HTTP-API's gebruiken met behulp van de orchestration-triggerbinding.

In de volgende voorbeeldcode ziet u een orchestratorfunctie die een uitgaande HTTP-aanvraag maakt:

[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
    }
}

Met behulp van de actie HTTP aanroepen kunt u de volgende acties uitvoeren in de orchestratorfuncties:

  • Roep HTTP-API's rechtstreeks aan vanuit indelingsfuncties, met enkele beperkingen die later worden genoemd.
  • Http 202-statuspeilingpatronen aan de clientzijde automatisch ondersteunen.
  • Gebruik Azure Managed Identities om geautoriseerde HTTP-aanroepen naar andere Azure-eindpunten uit te voeren.

De mogelijkheid om HTTP-API's rechtstreeks vanuit orchestratorfuncties te gebruiken, is bedoeld als een gemak voor een bepaalde set algemene scenario's. U kunt al deze functies zelf implementeren met behulp van activiteitsfuncties. In veel gevallen kunnen activiteitsfuncties u meer flexibiliteit bieden.

HTTP 202-verwerking

De API voor het aanroepen van HTTP kan automatisch de clientzijde van het polling-consumentenpatroon implementeren. Als een aangeroepen API een HTTP 202-antwoord retourneert met een locatieheader, controleert de orchestratorfunctie automatisch de locatieresource totdat een ander antwoord dan 202 wordt ontvangen. Dit antwoord is het antwoord dat wordt geretourneerd aan de orchestrator-functiecode.

Notitie

  1. Orchestrator-functies bieden ook systeemeigen ondersteuning voor het polling-consumentenpatroon aan de serverzijde, zoals beschreven in het bijhouden van Asynchrone bewerkingen. Deze ondersteuning betekent dat indelingen in de ene functie-app eenvoudig de orchestratorfuncties in andere functie-apps kunnen coördineren. Dit is vergelijkbaar met het subindelingsconcept , maar met ondersteuning voor communicatie tussen apps. Deze ondersteuning is met name handig voor het ontwikkelen van microservice-apps.
  2. Vanwege een tijdelijke beperking is het ingebouwde HTTP-pollingpatroon momenteel niet beschikbaar in JavaScript/TypeScript en Python.

Beheerde identiteiten

Durable Functions ondersteunt systeemeigen aanroepen naar API's die Microsoft Entra-tokens accepteren voor autorisatie. Deze ondersteuning maakt gebruik van door Azure beheerde identiteiten om deze tokens te verkrijgen.

De volgende code is een voorbeeld van een orchestratorfunctie. Met de functie worden geverifieerde aanroepen uitgevoerd om een virtuele machine opnieuw op te starten met behulp van de REST API van azure Resource Manager.

[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}");
    }
}

In het vorige voorbeeld is de parameter geconfigureerd voor het tokenSource verkrijgen van Microsoft Entra-tokens voor Azure Resource Manager. De tokens worden geïdentificeerd door de resource-URI https://management.core.windows.net/.default. In het voorbeeld wordt ervan uitgegaan dat de huidige functie-app lokaal wordt uitgevoerd of is geïmplementeerd als een functie-app met een beheerde identiteit. De lokale identiteit of de beheerde identiteit wordt ervan uitgegaan dat ze gemachtigd zijn om VM's in de opgegeven resourcegroep myRGte beheren.

Tijdens runtime retourneert de geconfigureerde tokenbron automatisch een OAuth 2.0-toegangstoken. De bron voegt het token vervolgens toe als bearer-token aan de autorisatieheader van de uitgaande aanvraag. Dit model is een verbetering ten opzichte van het handmatig toevoegen van autorisatieheaders aan HTTP-aanvragen om de volgende redenen:

  • Het vernieuwen van tokens wordt automatisch verwerkt. U hoeft zich geen zorgen te maken over verlopen tokens.
  • Tokens worden nooit opgeslagen in de duurzame indelingsstatus.
  • U hoeft geen code te schrijven om het verkrijgen van tokens te beheren.

U vindt een completer voorbeeld in het voorbeeld van vooraf gecompileerde C# RestartVMs.

Beheerde identiteiten zijn niet beperkt tot Azure-resourcebeheer. U kunt beheerde identiteiten gebruiken voor toegang tot elke API die Microsoft Entra Bearer-tokens accepteert, inclusief Azure-services van Microsoft en web-apps van partners. De web-app van een partner kan zelfs een andere functie-app zijn. Zie Azure-services die ondersteuning bieden voor Microsoft Entra-verificatie voor een lijst met Azure-services van Microsoft die ondersteuning bieden voor verificatie met Microsoft Entra-id.

Beperkingen

De ingebouwde ondersteuning voor het aanroepen van HTTP-API's is een handige functie. Dit is niet geschikt voor alle scenario's.

HTTP-aanvragen die worden verzonden door orchestratorfuncties en hun antwoorden worden geserialiseerd en behouden als berichten in de Durable Functions-opslagprovider. Dit permanente wachtrijgedrag zorgt ervoor dat HTTP-aanroepen betrouwbaar en veilig zijn voor het opnieuw afspelen van indelingen. Het permanente wachtrijgedrag heeft echter ook beperkingen:

  • Elke HTTP-aanvraag omvat extra latentie in vergelijking met een systeemeigen HTTP-client.
  • Afhankelijk van de geconfigureerde opslagprovider kunnen grote aanvraag- of antwoordberichten de indelingsprestaties aanzienlijk verminderen. Wanneer u bijvoorbeeld Azure Storage gebruikt, worden HTTP-nettoladingen die te groot zijn om in Azure Queue-berichten te passen, gecomprimeerd en opgeslagen in Azure Blob Storage.
  • Streaming, gesegmenteerde en binaire nettoladingen worden niet ondersteund.
  • De mogelijkheid om het gedrag van de HTTP-client aan te passen, is beperkt.

Als een van deze beperkingen van invloed kan zijn op uw use-case, kunt u in plaats daarvan overwegen om activiteitsfuncties en taalspecifieke HTTP-clientbibliotheken te gebruiken om uitgaande HTTP-aanroepen uit te voeren.

Notitie

Als u een .NET-ontwikkelaar bent, vraagt u zich misschien af waarom deze functie gebruikmaakt van de typen DurableHttpRequest en DurableHttpResponse in plaats van de ingebouwde typen .NET HttpRequestMessage en HttpResponseMessage .

Dit is een opzettelijke ontwerpkeuze. De belangrijkste reden is dat aangepaste typen ervoor zorgen dat gebruikers geen onjuiste veronderstellingen maken over het ondersteunde gedrag van de interne HTTP-client. Typen die specifiek zijn voor Durable Functions maken het ook mogelijk om het API-ontwerp te vereenvoudigen. Ze kunnen ook eenvoudiger speciale functies beschikbaar maken, zoals integratie van beheerde identiteiten en het polling consumer-patroon.

Uitbreidbaarheid (alleen.NET)

Het aanpassen van het gedrag van de interne HTTP-client van de indeling is mogelijk met behulp van Azure Functions .NET-afhankelijkheidsinjectie. Deze mogelijkheid kan nuttig zijn voor het aanbrengen van kleine gedragswijzigingen. Het kan ook handig zijn voor eenheidstests van de HTTP-client door mock-objecten te injecteren.

In het volgende voorbeeld ziet u hoe u afhankelijkheidsinjectie gebruikt om validatie van TLS/SSL-certificaten uit te schakelen voor orchestratorfuncties die externe HTTP-eindpunten aanroepen.

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,
        };
    }
}

Volgende stappen