HTTP-Features
Durable Functions verfügt über mehrere Features, die die Einbindung dauerhafter Orchestrierungen und Entitäten in HTTP-Workflows vereinfachen. In diesem Artikel werden einige dieser Features ausführlich erläutert.
Verfügbarmachen von HTTP-APIs
Orchestrierungen und Entitäten können mithilfe von HTTP-Anforderungen aufgerufen und verwaltet werden. Die Durable Functions-Erweiterung macht die integrierten HTTP-APIs verfügbar. Außerdem stellt sie APIs für die Interaktion mit Orchestrierungen und Entitäten aus über HTTP ausgelösten Funktionen heraus bereit.
Integrierte HTTP-APIs
Die Durable Functions-Erweiterung fügt dem Azure Functions-Host automatisch eine Reihe von HTTP-APIs hinzu. Diese APIs ermöglichen es Ihnen, mit Orchestrierungen und Entitäten zu interagieren und diese zu verwalten, ohne dass hierfür Programmieraufwand erforderlich ist.
Die folgenden integrierten HTTP-APIs werden unterstützt.
- Starten einer neuen Orchestrierung
- Abfragen der Orchestrierungsinstanz
- Beenden der Orchestrierungsinstanz
- Senden eines externen Ereignisses an eine Orchestrierung
- Löschen des Orchestrierungsverlaufs
- Senden eines Vorgangsereignisses an eine Entität
- Abrufen des Zustands einer Entität
- Abfragen der Liste der Entitäten
Im Artikel HTTP-APIs finden Sie eine vollständige Beschreibung aller integrierten HTTP-APIs, die von der Durable Functions-Erweiterung verfügbar gemacht werden.
Ermittlung der HTTP-API-URL
Die Orchestrierungsclientbindung macht APIs verfügbar, die zum Generieren praktischer HTTP-Antwortnutzlasten verwendet werden können. Sie kann beispielsweise eine Antwort mit Links zu Verwaltungs-APIs für eine bestimmte Orchestrierungsinstanz erstellen. Im Folgenden finden Sie Beispiele für eine HTTP-Triggerfunktion, die zeigt, wie diese API für eine neue Orchestrierungsinstanz verwendet wird:
// 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);
}
}
}
Das Starten einer Orchestratorfunktion mithilfe der oben gezeigten HTTP-Triggerfunktionen kann über einen beliebigen HTTP-Client erfolgen. Der folgende cURL-Befehl startet die Orchestratorfunktion DoWork
:
curl -X POST https://localhost:7071/orchestrators/DoWork -H "Content-Length: 0" -i
Im Folgenden finden Sie eine Beispielantwort für eine Orchestrierung, die abc123
als ID aufweist. Einige Details wurden aus Gründen der Übersichtlichkeit entfernt.
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"
}
Im vorherigen Beispiel entsprechen alle Felder, die auf Uri
enden, einer integrierten HTTP-API. Sie können diese APIs verwenden, um die Zielorchestrierungsinstanz zu verwalten.
Hinweis
Das Format der Webhook-URLs hängt davon ab, welche Version des Azure Functions-Hosts Sie ausführen. Das obige Beispiel gilt für den Azure Functions 2.0-Host.
Eine Beschreibung aller integrierten HTTP-APIs finden Sie in der HTTP-API-Referenz.
Nachverfolgen von asynchronen Vorgängen
Die oben erwähnte HTTP-Antwort wurde als Hilfe bei der Implementierung von asynchronen HTTP-APIs mit langer Ausführungsdauer per Durable Functions konzipiert. Dieses Muster wird manchmal auch als Polling Consumer Pattern (Consumerabrufmuster) bezeichnet. Der Client/Server-Datenfluss funktioniert wie folgt:
- Der Client übermittelt eine HTTP-Anforderung, um einen Prozess mit langer Ausführungsdauer zu starten, z. B. eine Orchestratorfunktion.
- Der HTTP-Zieltrigger gibt eine HTTP 202-Antwort mit einem Location-Header zurück, der den Wert „statusQueryGetUri“ aufweist.
- Der Client fragt die URL im Location-Header ab. Der Client erhält weiterhin die HTTP 202-Antworten mit dem Location-Header.
- Wenn die Instanz abgeschlossen wurde (oder zu einem Fehler geführt hat), gibt der Endpunkt im Location-Header als Antwort „HTTP 200“ zurück.
Dieses Protokoll ermöglicht die Koordination von Prozessen mit langer Ausführungsdauer mit externen Clients oder Diensten, die einen HTTP-Endpunkt abfragen können und den Location-Header befolgen. Die Client- und Serverimplementierungen dieses Musters sind in die Durable Functions-HTTP-APIs integriert.
Hinweis
Standardmäßig unterstützen alle HTTP-basierten Aktionen, die von Azure Logic Apps bereitgestellt werden, das Standardmuster für asynchrone Vorgänge. Diese Funktion ermöglicht das Einbetten eines Durable Functions-Elements als Teil eines Logic Apps-Workflows. Weitere Informationen zur Unterstützung von Logik-Apps für asynchrone HTTP-Muster finden Sie in der Dokumentation zu Workflowaktionen und -triggern für Azure Logic Apps.
Hinweis
Die Interaktion mit Orchestrierungen kann von jedem Funktionstyp aus erfolgen, nicht nur durch über HTTP ausgelöste Funktionen.
Weitere Informationen zum Verwalten von Orchestrierungen und Entitäten mithilfe von Client-APIs finden Sie im Artikel zum Verwalten von Instanzen.
Verarbeiten von HTTP-APIs
Wie unter Codeeinschränkungen für Orchestratorfunktionen beschrieben, können Orchestratorfunktionen E/A-Vorgänge nicht direkt ausführen. Stattdessen werden in der Regel Aktivitätsfunktionen aufgerufen, die die E/A-Vorgänge ausführen.
Ab Durable Functions 2.0 können Orchestrierungen mithilfe der Orchestrierungstriggerbindung HTTP-APIs nativ nutzen.
Der folgende Beispielcode zeigt eine Orchestratorfunktion, die eine ausgehende HTTP-Anforderung vornimmt:
[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
}
}
Mit der Aktion „call HTTP“ sind in Ihren Orchestratorfunktionen folgende Aktionen möglich:
- Direktes Aufrufen von HTTP-APIs aus Orchestrierungsfunktionen mit einigen später beschriebenen Einschränkungen
- Automatisches Unterstützen clientseitiger HTTP 202-Statusabrufmuster
- Verwenden verwalteter Azure-Identitäten für autorisierte HTTP-Aufrufe an andere Azure-Endpunkte
Die Möglichkeit, HTTP-APIs direkt von Orchestratorfunktionen zu nutzen, ist bei einigen häufigen Szenarien sehr praktisch. Sie können alle diese Features selbst mithilfe von Aktivitätsfunktionen implementieren. In vielen Fällen bieten Ihnen Aktivitätsfunktionen mehr Flexibilität.
HTTP 202-Verarbeitung
Die API „call HTTP“ kann die Clientseite des Polling Consumer Pattern automatisch implementieren. Wenn eine aufgerufene API eine HTTP 202-Antwort mit einem Location-Header zurückgibt, ruft die Orchestratorfunktion automatisch die Location-Ressource ab, bis eine Antwort zurückgegeben wird, die nicht 202 ist. Dies ist die Antwort, die an den Orchestratorfunktionscode zurückgegeben wird.
Hinweis
- Orchestratorfunktionen bieten auch native Unterstützung für das serverseitige Polling Consumer Pattern, wie unter Nachverfolgen von asynchronen Vorgängen beschrieben. Diese Unterstützung bedeutet, dass Orchestrierungen in einer Funktions-App die Orchestratorfunktionen in anderen Funktions-Apps problemlos koordinieren können. Dies ähnelt dem Konzept der untergeordneten Orchestrierung, jedoch mit Unterstützung für die App-übergreifende Kommunikation. Diese Unterstützung ist insbesondere beim Entwickeln von Apps im Stil von Microservices praktisch.
- Aufgrund einer vorübergehenden Einschränkung ist das integrierte HTTP-Abrufmuster derzeit in JavaScript/TypeScript und Python nicht verfügbar.
Verwaltete Identitäten
Durable Functions bietet native Unterstützung für das Aufrufen der APIs, die Microsoft Entra-Token für die Autorisierung akzeptieren. Diese Unterstützung verwendet verwaltete Azure -Identitäten, um diese Token abzurufen.
Der folgende Code ist ein Beispiel für eine .NET-Orchestratorfunktion. Die Funktion nimmt authentifizierte Aufrufe zum Neustart eines virtuellen Computers mithilfe der Virtual Machines-REST-API von Azure Resource Manager vor.
[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}");
}
}
Im vorherigen Beispiel ist der tokenSource
-Parameter so konfiguriert, dass Microsoft Entra-Token für Azure Resource Manager abgerufen werden. Die Token werden durch den Ressourcen-URI https://management.core.windows.net/.default
identifiziert. Im Beispiel wird davon ausgegangen, dass die aktuelle Funktions-App entweder lokal ausgeführt wird oder als eine Funktions-App mit einer verwalteten Identität bereitgestellt wurde. Es wird davon ausgegangen, dass die lokale Identität oder die verwaltete Identität über Berechtigungen zum Verwalten virtueller Computer in der angegebenen Ressourcengruppe myRG
verfügt.
Zur Laufzeit gibt die konfigurierte Tokenquelle automatisch ein OAuth 2.0-Zugriffstoken zurück. Die Quelle fügt das Token dann als Bearertoken dem Autorisierungsheader der ausgehenden Anforderung hinzu. Dieses Modell ist aus folgenden Gründen besser als das manuelle Hinzufügen eines Autorisierungsheaders zu HTTP-Anforderungen:
- Die Tokenaktualisierung wird automatisch durchgeführt. Sie müssen sich nicht um abgelaufene Token kümmern.
- Token werden niemals im Zustand der dauerhaften Orchestrierung gespeichert.
- Sie müssen keinen Code schreiben, um den Tokenabruf zu verwalten.
Ein ausführlicheres Beispiel finden Sie in den vorkompilierten C#-Beispielen für „RestartVMs“.
Verwaltete Identitäten sind nicht auf die Azure-Ressourcenverwaltung beschränkt. Sie können verwaltete Identitäten für den Zugriff auf beliebige APIs verwenden, die Microsoft Entra-Bearertoken akzeptieren, einschließlich der Azure-Dienste von Microsoft oder Web-Apps von Partnern. Die Web-App eines Partners kann sogar eine andere Funktions-App sein. Eine Liste mit Azure-Diensten von Microsoft, die die Authentifizierung mit Microsoft Entra unterstützen, finden Sie unter Azure-Dienste, die die Microsoft Entra-Authentifizierung unterstützen.
Begrenzungen
Die integrierte Unterstützung für das Aufrufen von HTTP-APIs ist ein praktisches Feature. Es ist nicht für alle Szenarien geeignet.
Von Orchestratorfunktionen gesendete HTTP-Anforderungen und ihre Antworten werden serialisiert und im Durable Functions-Speicheranbieter dauerhaft beibehalten. Dieses persistente Queuingverhalten stellt sicher, dass HTTP-Aufrufe zuverlässig und beim Wiedergeben der Orchestrierung sicher sind. Für das persistente Queuingverhalten gelten jedoch ebenfalls Einschränkungen:
- Jede HTTP-Anforderung umfasst eine zusätzliche Wartezeit im Vergleich zu einem nativen HTTP-Client.
- Abhängig vom konfigurierten Speicheranbieter können große Anforderungs- oder Antwortnachrichten die Orchestrierungsleistung erheblich beeinträchtigen. Wenn Sie beispielsweise Azure Storage verwenden, werden HTTP-Payloads, die zu groß sind, um in Azure-Warteschlangennachrichten zu passen, komprimiert und in Azure Blob Storage gespeichert.
- Streaming und segmentierte und binäre Nutzlasten werden nicht unterstützt.
- Die Möglichkeit, das Verhalten des HTTP-Clients anzupassen, ist begrenzt.
Wenn Ihr Anwendungsfall durch eine dieser Einschränkungen beeinträchtigt wird, nutzen Sie stattdessen ggf. Aktivitätsfunktionen und sprachspezifische HTTP-Clientbibliotheken, um ausgehende HTTP-Aufrufe vorzunehmen.
Hinweis
Wenn Sie .NET-Entwickler sind, fragen Sie sich vielleicht, warum dieses Feature die Typen DurableHttpRequest und DurableHttpResponse anstelle der integrierten .NET-Typen HttpRequestMessage und HttpResponseMessage nutzt.
Dies ist eine bewusste Entscheidung. In erster Linie stellen benutzerdefinierte Typen sicher, dass Benutzer keine falschen Annahmen über unterstützte Verhaltensweisen des internen HTTP-Clients treffen. Typen, die spezifisch für Durable Functions sind, tragen auch zu einer Vereinfachung des API-Designs bei. Außerdem können Sie auf einfachere Weise spezielle Features wie die Integration verwalteter Identitäten und das Polling Consumer Pattern verfügbar machen.
Erweiterbarkeit (nur .NET)
Das Anpassen des Verhaltens des internen HTTP-Clients der Orchestrierung kann mithilfe von Azure Functions .NET-Abhängigkeitsinjektion erfolgen. Diese Funktion kann nützlich sein, um geringfügige Verhaltensänderungen vorzunehmen. Sie kann auch hilfreich sein, um Komponententests für den HTTP-Client durch Einfügen von Pseudoobjekten durchzuführen.
Das folgende Beispiel veranschaulicht die Verwendung der Abhängigkeitsinjektion, um die TLS/SSL-Zertifikatüberprüfung für Orchestratorfunktionen zu deaktivieren, die externe HTTP-Endpunkte aufrufen.
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,
};
}
}