HTTP 功能
Durable Functions 有數個功能,可讓您輕鬆地將永久性協調流程和實體併入 HTTP 工作流程。 本文將詳細說明其中一些功能。
公開 HTTP API
您可以使用 HTTP 要求來叫用和管理協調流程和實體。 Durable Functions 延伸模組會公開 HTTP API。 其也提供 API 來與 HTTP 觸發函數內的協調流程和實體互動。
內建 HTTP API
Durable Functions 延伸模組會自動將一組 HTTP API 新增至 Azure Functions 主機。 透過這些 API,您可以與協調流程和實體互動和加以管理,而不需撰寫任何程式碼。
支援下列內建 HTTP API。
如需 Durable Functions 延伸模組所公開之所有內建 HTTP API 的完整描述,請參閱 HTTP API 一文。
HTTP API URL 探索
協調流程用戶端繫結會公開 API,以產生方便的 HTTP 回應承載。 例如,其可以建立回應,其中包含特定協調流程執行個體之管理 API 的連結。 下列範例示範 HTTP 觸發程序函數,示範如何將此 API 用於新的協調流程執行個體:
// 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);
}
}
}
使用先前顯示的 HTTP 觸發程序函數啟動協調器函數,可以使用任何 HTTP 用戶端來完成。 下列 cURL 命令會啟動名為 DoWork
的協調器函數:
curl -X POST https://localhost:7071/orchestrators/DoWork -H "Content-Length: 0" -i
接下來是協調流程的範例回應,該協調流程具有 abc123
做為其識別碼。 為清楚起見,已移除某些詳細資料。
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"
}
在上一個範例中,Uri
中結尾的每個欄位都會對應至內建 HTTP API。 您可以使用這些 API 來管理目標協調流程執行個體。
注意
Webhook URL 的格式依據您執行的 Azure Functions 主機版本會有所不同。 上述範例適用於 Azure Functions 2.0 主機。
如需所有內建 HTTP API 的描述,請參閱 HTTP API 參考。
非同步作業追蹤
先前所述之 HTTP 回應的設計目的,是協助搭配長期函式實作長時間執行 HTTP 非同步 API。 此模式有時候稱為「輪詢取用者模式」。 用戶端/伺服器流量運作方式如下:
- 用戶端會發出 HTTP 要求,以啟動長時間執行程序,例如協調器函數。
- 目標 HTTP 觸發程序會傳回 HTTP 202 回應,其位置標頭具有值「statusQueryGetUri」。
- 用戶端會輪詢位置標頭中的 URL。 用戶端會繼續查看具有位置標頭的 HTTP 202 回應。
- 當執行個體完成或失敗時,位置標頭中的端點會傳回 HTTP 200。
此通訊協定可以協調長時間執行程序與外部用戶端或服務,其可以輪詢 HTTP 端點,並且遵循位置標頭。 此模式的用戶端和伺服器實作都內建於 Durable Functions HTTP API 中。
注意
根據預設,Azure Logic Apps 提供的所有 HTTP 型動作皆支援標準的非同步作業模式。 這項功能可以嵌入長期執行長期函式,作為 Logic Apps 工作流程的一部分。 您在 Azure Logic Apps 工作流程動作和觸發程序文件中找到 Logic Apps 支援非同步 HTTP 模式的詳細資訊。
注意
與協調流程的互動可以從任何函數類型完成,而不只是 HTTP 觸發的函數。
如需如何使用用戶端 API 管理協調流程和實體的詳細資訊,請參閱執行個體管理一文。
取用 HTTP API
如協調器函數程式碼條件約束中所述,協調器函數無法直接執行 I/O。 相反地,其通常會呼叫執行 I/O 作業的活動函數。
從 Durable Functions 2.0 開始,協調流程可以使用協調流程觸發程序繫結,以原生方式取用 HTTP API。
下列範例程式碼顯示發出輸出 HTTP 要求的協調器函數:
[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
}
}
藉由使用「呼叫 HTTP」動作,您可以在協調器函數中執行下列動作:
- 直接從協調流程函數呼叫 HTTP API,並具有稍後所述的一些限制。
- 自動支援用戶端 HTTP 202 狀態輪詢模式。
- 使用 Azure 受控識別,對其他 Azure 端點進行授權的 HTTP 呼叫。
直接從協調器函數取用 HTTP API 的能力,旨在為一組常見情節提供便利性。 您可以使用活動函數自行實作所有這些功能。 在許多案例下,活動函數可能會讓您更有彈性。
HTTP 202 處理
「呼叫 HTTP」API 可以自動實作輪詢取用者模式的用戶端。 如果呼叫的 API 傳回具有位置標頭的 HTTP 202 回應,協調器函數會自動輪詢位置資源,直到收到 202 以外的回應為止。 此回應將會是傳回給協調器函數程式碼的回應。
注意
受控識別
Durable Functions 原生支援對接受 Microsoft Entra 權杖進行授權之 API 的呼叫。 此支援會使用 Azure 受控識別來取得這些權杖。
下列程式碼是協調器函數的範例。 函數會進行已驗證的呼叫,以使用 Azure Resource Manager 虛擬機器 REST API 重新啟動虛擬機器。
[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}");
}
}
在上一個範例中,會將 tokenSource
參數設定為取得 Azure Resource Manager 的 Microsoft Entra 權杖。 權杖是由資源 URI https://management.core.windows.net/.default
識別。 此範例假設目前的函數應用程式是在本地執行,或是部署為具有受控識別的函數應用程式。 假設本地身分識別或受控識別有權管理指定資源群組 myRG
中的 VM。
在執行階段,設定的權杖來源會自動傳回 OAuth 2.0 存取權杖。 然後,來源會將權杖以持有人權杖的形式新增至傳出要求的授權標頭。 此模型是手動將授權標頭新增至 HTTP 要求的改善,原因如下:
- 會自動處理權杖重新整理。 您不需要擔心權杖過期。
- 永遠不會在永久性協調流程狀態中儲存權杖。
- 您不需要撰寫任何程式碼來管理權杖取得。
您可以在先行編譯的 C# RestartVM 樣本中找到更完整的範例。
受控識別不限於 Azure 資源管理。 您可以使用受控識別,來存取接受 Microsoft Entra 持有人權杖的任何 API,包括來自 Microsoft 的 Azure 服務,以及來自合作夥伴的 Web 應用程式。 合作夥伴的 Web 應用程式甚至可以是另一個函數應用程式。 如需支援使用 Microsoft Entra 識別碼進行驗證的 Microsoft Azure 服務清單,請參閱支援 Microsoft Entra 驗證的 Azure 服務。
限制
呼叫 HTTP API 的內建支援是一項便利功能。 其不適用於所有情節。
協調器函數所傳送的 HTTP 要求及其回應會以 Durable Functions 儲存體提供者中訊息的形式序列化與保存。 此持續性佇列行為可確保 HTTP 呼叫是可靠且安全,以便重新執行協調流程。 不過,持續性佇列行為也有限制:
- 相較於原生 HTTP 用戶端,每個 HTTP 要求都會牽涉到額外的延遲。
- 根據設定的儲存體提供者,大型要求或回應訊息可能會大幅降低協調流程效能。 例如,使用 Azure 儲存體時,無法容納 Azure 佇列訊息的 HTTP 承載會壓縮並儲存在 Azure Blob 儲存體中。
- 不支援串流、區塊化和二進位承載。
- 自訂 HTTP 用戶端行為的能力有限。
如果其中任何一項限制可能會影響您的使用案例,請考慮改用活動函數和語言特定的 HTTP 用戶端程式庫來進行輸出 HTTP 呼叫。
注意
如果您是 .NET 開發人員,您可能會想知道此功能為何使用 DurableHttpRequest 和 DurableHttpResponse 類型,而不是內建的 .NET HttpRequestMessage 和 HttpResponseMessage 類型。
這是刻意設計的選擇。 主要原因是自訂類型有助於確保使用者不會對內部 HTTP 用戶端支援的行為做出不正確的假設。 Durable Functions 特有的類型也可簡化 API 設計。 其也可以更輕鬆地提供特殊功能,例如受控識別整合和輪詢取用者模式。
擴充性 (僅 .NET)
您可以使用 Azure Functions .NET 相依性插入,自訂協調流程內部 HTTP 用戶端的行為。 這項功能對於進行小型行為變更很有用。 其在插入模擬物件來單元測試 HTTP 用戶端時也很有用。
下列範例示範如何使用相依性插入,來停用呼叫外部 HTTP 端點之協調器函數的 TLS/SSL 憑證驗證。
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,
};
}
}