Funzionalità HTTP

Durable Functions include diverse funzionalità che semplificano l'incorporazione di orchestrazioni ed entità durevoli nei flussi di lavoro HTTP. Questo articolo illustra in dettaglio alcune di queste funzionalità.

Esposizione di API HTTP

Le orchestrazioni e le entità possono essere richiamate e gestite tramite richieste HTTP. L'estensione Durable Functions espone le API HTTP predefinite. Fornisce anche API per interagire con orchestrazioni ed entità dall'interno di funzioni attivate da HTTP.

API HTTP predefinite

L'estensione Durable Functions aggiunge automaticamente un set di API HTTP all'host Funzioni di Azure. Con queste API è possibile interagire con e gestire orchestrazioni ed entità senza scrivere codice.

Sono supportate le API HTTP predefinite seguenti.

Vedere l'articolo API HTTP per una descrizione completa di tutte le API HTTP predefinite esposte dall'estensione Durable Functions.

Rilevamento dell'URL di API HTTP

L'associazione client di orchestrazione espone le API che possono generare utili payload di risposta HTTP. Ad esempio, può creare una risposta contenente collegamenti alle API di gestione per un'istanza di orchestrazione specifica. Gli esempi seguenti illustrano una funzione trigger HTTP che illustra come usare questa API per una nuova istanza di orchestrazione:

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

L'avvio di una funzione dell'agente di orchestrazione usando le funzioni http-trigger illustrate in precedenza può essere eseguita usando qualsiasi client HTTP. Il comando cURL seguente avvia una funzione dell'agente di orchestrazione denominata DoWork:

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

Di seguito è riportato un esempio di risposta per un'orchestrazione con abc123 come ID. Alcuni dettagli sono stati rimossi per maggiore chiarezza.

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

Nell'esempio precedente, ognuno dei campi che terminano Uri corrisponde a un'API HTTP predefinita. È possibile usare queste API per gestire l'istanza di orchestrazione di destinazione.

Nota

Il formato degli URL del webhook dipende dalla versione dell'host Funzioni di Azure in esecuzione. L'esempio precedente è relativo all'host Funzioni di Azure 2.0.

Per una descrizione di tutte le API HTTP predefinite, vedere le informazioni di riferimento sull'API HTTP.

Verifica di operazioni asincrone

La risposta HTTP indicata in precedenza è stata concepita per semplificare l'implementazione di API asincrone a esecuzione prolungata con Durable Functions. Questo modello viene talvolta definito modello consumer di polling. Il flusso client/server funziona come segue:

  1. Il client invia una richiesta HTTP per avviare un processo a esecuzione prolungata, ad esempio una funzione dell'agente di orchestrazione.
  2. Il trigger HTTP di destinazione restituisce una risposta HTTP 202 con un'intestazione Location con il valore "statusQueryGetUri".
  3. Il client esegue il polling dell'URL nell'intestazione Location. Il client continua a visualizzare le risposte HTTP 202 con un'intestazione Location.
  4. Al termine o all'esito negativo dell'istanza, l'endpoint nell'intestazione Percorso restituisce HTTP 200.

Questo protocollo consente il coordinamento dei processi a esecuzione prolungata con client o servizi esterni che possono eseguire il polling di un endpoint HTTP e seguire l'intestazione Location. Le implementazioni client e server di questo modello sono integrate nelle API HTTP di Durable Functions.

Nota

Per impostazione predefinita, tutte le azioni basate su HTTP fornite dalle App per la logica di Azure supportano il modello di operazione asincrono standard. Questa funzionalità rende possibile incorporare una funzione permanente a esecuzione prolungata come parte di un flusso di lavoro di App per la logica. Per altre informazioni sul supporto di App per la logica per modelli HTTP asincroni, vedere la documentazione relativa alle azioni e ai trigger del flusso di lavoro App per la logica di Azure.

Nota

Le interazioni con le orchestrazioni possono essere eseguite da qualsiasi tipo di funzione, non solo da funzioni attivate da HTTP.

Per altre informazioni su come gestire orchestrazioni ed entità usando le API client, vedere l'articolo Gestione delle istanze.

Uso delle API HTTP

Come descritto nei vincoli del codice della funzione dell'agente di orchestrazione, le funzioni dell'agente di orchestrazione non possono eseguire direttamente operazioni di I/O. In genere chiamano funzioni di attività che eseguono operazioni di I/O.

A partire da Durable Functions 2.0, le orchestrazioni possono usare in modo nativo le API HTTP usando l'associazione di trigger di orchestrazione.

Il codice di esempio seguente mostra una funzione dell'agente di orchestrazione che effettua una richiesta HTTP in uscita:

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

Usando l'azione "chiama HTTP", è possibile eseguire le azioni seguenti nelle funzioni dell'agente di orchestrazione:

La possibilità di usare le API HTTP direttamente dalle funzioni dell'agente di orchestrazione è concepita per praticità per un determinato set di scenari comuni. È possibile implementare tutte queste funzionalità usando funzioni di attività. In molti casi, le funzioni di attività potrebbero offrire maggiore flessibilità.

Gestione HTTP 202

L'API "chiama HTTP" può implementare automaticamente il lato client del modello consumer di polling. Se un'API denominata restituisce una risposta HTTP 202 con un'intestazione Location, la funzione dell'agente di orchestrazione esegue automaticamente il polling della risorsa Location fino a ricevere una risposta diversa da 202. Questa risposta sarà la risposta restituita al codice della funzione dell'agente di orchestrazione.

Nota

  1. Le funzioni dell'agente di orchestrazione supportano anche in modo nativo il modello consumer di polling sul lato server, come descritto in Rilevamento delle operazioni asincrone. Questo supporto significa che le orchestrazioni in un'app per le funzioni possono coordinare facilmente le funzioni dell'agente di orchestrazione in altre app per le funzioni. Questo è simile al concetto di orchestrazione secondaria, ma con il supporto per la comunicazione tra app. Questo supporto è particolarmente utile per lo sviluppo di app in stile microservizio.
  2. A causa di una limitazione temporanea, il modello di polling HTTP predefinito non è attualmente disponibile in JavaScript/TypeScript e Python.

Identità gestite

Durable Functions supporta in modo nativo le chiamate alle API che accettano token Microsoft Entra per l'autorizzazione. Questo supporto usa le identità gestite di Azure per acquisire questi token.

Il codice seguente è un esempio di funzione dell'agente di orchestrazione. La funzione effettua chiamate autenticate per riavviare una macchina virtuale usando l'API REST delle macchine virtuali di 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}");
    }
}

Nell'esempio precedente il tokenSource parametro è configurato per acquisire i token Microsoft Entra per Azure Resource Manager. I token sono identificati dall'URI https://management.core.windows.net/.defaultdella risorsa . L'esempio presuppone che l'app per le funzioni corrente sia in esecuzione in locale o sia stata distribuita come app per le funzioni con un'identità gestita. Si presuppone che l'identità locale o l'identità gestita disponga dell'autorizzazione per gestire le macchine virtuali nel gruppo myRGdi risorse specificato.

In fase di esecuzione, l'origine del token configurata restituisce automaticamente un token di accesso OAuth 2.0. L'origine aggiunge quindi il token come token di connessione all'intestazione Authorization della richiesta in uscita. Questo modello è un miglioramento rispetto all'aggiunta manuale di intestazioni di autorizzazione alle richieste HTTP per i motivi seguenti:

  • L'aggiornamento del token viene gestito automaticamente. Non è necessario preoccuparsi dei token scaduti.
  • I token non vengono mai archiviati nello stato di orchestrazione durevole.
  • Non è necessario scrivere codice per gestire l'acquisizione di token.

È possibile trovare un esempio più completo nell'esempio C# RestartVMs precompilato.

Le identità gestite non sono limitate alla gestione delle risorse di Azure. È possibile usare le identità gestite per accedere a qualsiasi API che accetta token di connessione di Microsoft Entraer, inclusi i servizi di Azure di Microsoft e le app Web dei partner. Un'app Web di un partner può anche essere un'altra app per le funzioni. Per un elenco dei servizi di Azure di Microsoft che supportano l'autenticazione con Microsoft Entra ID, vedere Servizi di Azure che supportano l'autenticazione di Microsoft Entra.

Limiti

Il supporto predefinito per chiamare le API HTTP è una funzionalità di praticità. Non è appropriato per tutti gli scenari.

Le richieste HTTP inviate dalle funzioni dell'agente di orchestrazione e dalle relative risposte vengono serializzate e rese persistenti come messaggi nel provider di archiviazione Durable Functions. Questo comportamento di accodamento permanente garantisce che le chiamate HTTP siano affidabili e sicure per la riproduzione dell'orchestrazione. Tuttavia, il comportamento di accodamento permanente presenta anche limitazioni:

  • Ogni richiesta HTTP comporta una latenza aggiuntiva rispetto a un client HTTP nativo.
  • A seconda del provider di archiviazione configurato, i messaggi di richiesta o risposta di grandi dimensioni possono ridurre significativamente le prestazioni di orchestrazione. Ad esempio, quando si usa Archiviazione di Azure, i payload HTTP troppo grandi per adattarsi ai messaggi della coda di Azure vengono compressi e archiviati nell'archivio BLOB di Azure.
  • I payload di streaming, blocchi e binari non sono supportati.
  • La possibilità di personalizzare il comportamento del client HTTP è limitata.

Se una di queste limitazioni può influire sul caso d'uso, prendere in considerazione l'uso di funzioni di attività e librerie client HTTP specifiche del linguaggio per effettuare chiamate HTTP in uscita.

Nota

Gli sviluppatori .NET potrebbero chiedersi perché questa funzionalità usa i tipi DurableHttpRequest e DurableHttpResponse anziché i tipi .NET HttpRequestMessage e HttpResponseMessage predefiniti.

Questa scelta di progettazione è intenzionale. Il motivo principale è che i tipi personalizzati aiutano a garantire che gli utenti non facciano ipotesi errate sui comportamenti supportati del client HTTP interno. I tipi specifici di Durable Functions consentono anche di semplificare la progettazione dell'API. Possono anche rendere più facilmente disponibili funzionalità speciali come l'integrazione delle identità gestite e il modello consumer di polling.

Estendibilità (solo.NET)

La personalizzazione del comportamento del client HTTP interno dell'orchestrazione è possibile usando Funzioni di Azure inserimento delle dipendenze .NET. Questa capacità può essere utile per apportare piccole modifiche comportamentali. Può anche essere utile per eseguire unit test del client HTTP inserendo oggetti fittizi.

L'esempio seguente illustra l'uso dell'inserimento delle dipendenze per disabilitare la convalida del certificato TLS/SSL per le funzioni dell'agente di orchestrazione che chiamano endpoint HTTP esterni.

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

Passaggi successivi