Поделиться через


Функции HTTP

Durable Functions имеет несколько возможностей, которые облегчают интеграцию долговечных оркестраций и сущностей в рабочие процессы HTTP. В этой статье подробно рассматриваются некоторые из этих функций.

Предоставление API-интерфейсов HTTP

Оркестрации и сущности могут вызываться и управляться с помощью HTTP-запросов. Расширение Durable Functions предоставляет встроенные API HTTP. Оно также предоставляет API для взаимодействия с оркестрациями и сущностями из HTTP-триггерных функций.

Встроенные API HTTP

Расширение Durable Functions автоматически добавляет набор API HTTP в узел Azure Functions. С помощью этих API-интерфейсов можно взаимодействовать и управлять согласованиями и сущностями без написания кода.

Поддерживаются следующие встроенные API-интерфейсы HTTP.

См. статью HTTP APIs для полного описания всех встроенных HTTP API, предоставляемых расширением Durable Functions.

Обнаружение URL-адреса API HTTP

Привязка клиента оркестрации предоставляет 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-триггером в одном приложении-функции, настройте уникальные route для каждой функции, чтобы избежать конфликтов маршрутов. Использование параметризованного маршрута, например orchestrators/{functionName} (как показано в нескольких предыдущих примерах), позволяет одной начальной функции HTTP запускать любой оркестратор по имени, который часто является самым простым подходом.

Запуск функции оркестратора с помощью функций 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 можно использовать для управления целевым инстансом оркестрации.

Замечание

Формат URL-адресов веб-перехватчика зависит от используемой версии узла Azure Functions. Предыдущий пример предназначен для узла Azure Functions 2.0.

Описание всех встроенных API HTTP см. в справочнике по API HTTP.

Отслеживание асинхронных операций

Упомянутый ранее HTTP-ответ предназначен для облегчения реализации длительных асинхронных API HTTP с использованием Durable Functions. Этот шаблон иногда называется шаблоном опроса потребителей. Поток клиента или сервера работает следующим образом:

  1. Клиент отправляет запрос HTTP для запуска длительного процесса, например функции оркестратора.
  2. Целевой триггер HTTP возвращает ответ HTTP 202 с заголовком Location со значением "statusQueryGetUri".
  3. Клиент опрашивает URL-адрес по заголовку Location. Он продолжает просматривать ответы HTTP 202 с заголовком Location.
  4. При завершении (или сбое) экземпляра конечная точка в заголовке Location возвращает код HTTP 200.

Этот протокол позволяет координировать долго выполняющиеся процессы с внешними клиентами или службами, которые могут опрашивать конечную точку HTTP и следовать за заголовком Location. Как клиентские, так и серверные реализации этого шаблона встроены в Durable Functions API HTTP.

Замечание

По умолчанию все действия на основе HTTP, предоставляемые Azure Logic Apps поддерживают стандартный шаблон асинхронной операции. Эта возможность позволяет внедрять долго выполняющиеся устойчивые функции в рамках рабочего процесса Logic Apps. Дополнительные сведения о поддержке logic Apps для асинхронных шаблонов HTTP см. в документации по действиям рабочего процесса Azure Logic Apps и триггерам.

Замечание

Взаимодействие с оркестрациями можно осуществлять из любого типа функции, а не только с помощью функций, активируемых HTTP.

Для получения более подробной информации об управлении оркестрациями и сущностями с помощью клиентских API см. статью об управлении экземплярами.

Использование API-интерфейсов HTTP

Как описано в ограничениях кода оркестратора, функции оркестратора не могут напрямую выполнять операции ввода-вывода. Вместо этого они обычно вызывают активности, которые выполняют операции ввода-вывода.

Начиная с версии Durable Functions 2.0 оркестрация может изначально использовать API HTTP с помощью привязки триггера orchestration.

В следующем примере кода показана функция оркестратора, выполняющая исходящий HTTP-запрос:

[FunctionName(nameof(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
    }
}

Замечание

Вы можете задаться вопросом, почему эта функция использует типы DurableHttpRequest и DurableHttpResponse вместо встроенных типов .NET HttpRequestMessage и HttpResponseMessage.

Такой выбор дизайна является намеренным. Основная причина заключается в том, что пользовательские типы помогают убедиться в том, что пользователи не делают неправильные предположения о поддерживаемых поведениях внутреннего HTTP-клиента. Типы, относящиеся к Durable Functions, также позволяют упростить проектирование API. Они также могут более легко сделать доступными специальные функции, такие как интеграция управляемых удостоверений и шаблон опроса потребителей.

С помощью действия "вызов HTTP" можно выполнять следующие действия в функциях оркестратора:

  • Вызывать API HTTP непосредственно из функций оркестрации с некоторыми ограничениями, упомянутыми ниже.
  • Автоматически поддерживать шаблоны опроса состояния HTTP 202 на стороне клиента.
  • Используйте Управляемые удостоверения Azure для выполнения авторизованных HTTP-вызовов к другим конечным точкам Azure.

Возможность использования HTTP API напрямую из функций оркестратора предназначена в качестве удобства для определенного набора распространенных сценариев. Все эти возможности можно реализовать самостоятельно с помощью функций активности. Во многих случаях функции действий могут обеспечить большую гибкость.

Обработка HTTP 202 (только .NET)

API «вызов HTTP» может автоматически реализовать клиентскую сторону шаблона поллинга потребителя. Если вызываемый API возвращает ответ HTTP 202 с заголовком Location, функция оркестратора автоматически опрашивает ресурс расположения, пока не получит ответ, отличный от 202. Этот ответ будет возвращен в код функции оркестратора.

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

    // HTTP automatic polling on 202 response is enabled by default in .NET in-process.
    DurableHttpResponse response = 
        await context.CallHttpAsync(HttpMethod.Get, url);
}

Замечание

  • Функции Orchestrator также изначально поддерживают шаблон потребителя с опросом на стороне сервера, описанный в отслеживании асинхронных операций. Такая поддержка означает, что оркестровки в одном приложении-функции могут легко координировать оркестраторов в других приложениях-функциях. Это похоже на концепцию подоркестрации, но с поддержкой взаимодействия между приложениями. Эта поддержка особенно полезна при разработке приложений в стиле микрослужб.
  • Встроенный шаблон опроса HTTP в настоящее время доступен только в узле .NET.
  • Шаблон опроса включен по умолчанию в .NET внутри процесса, но отключен по умолчанию в .NET изолированном окружении. Если вы хотите включить его в .NET Isolated, обратитесь к образцу кода и задайте для аргумента asynchronousPatternEnabled значение true.
  • Шаблон автоматического опроса HTTP поддерживается в изолированной среде Durable Functions .NET, начиная с версии v1.5.0 или позднее.

Управляемые идентичности

Durable Functions изначально поддерживает вызовы API, которые принимают маркеры Microsoft Entra для авторизации. Эта поддержка использует управляемые удостоверения Azure для получения этих токенов.

Следующий код является примером функции оркестратора. Функция выполняет вызовы, прошедшие проверку подлинности, чтобы перезапустить виртуальную машину с помощью REST API 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}");
    }
}

В предыдущем примере параметр tokenSource настроен для получения маркеров Microsoft Entra для Azure Resource Manager. Маркеры определяются URI ресурса https://management.core.windows.net/.default. Предполагается, что в этом примере текущее функциональное приложение выполняется локально или развернуто как функциональное приложение с управляемым удостоверением. Предполагается, что локальное удостоверение или управляемое удостоверение имеет разрешение на управление виртуальными машинами в указанной группе myRGресурсов.

Во время выполнения настроенный источник маркера автоматически возвращает маркер доступа OAuth 2.0. Затем источник добавляет маркер типа Bearer в заголовок Authorization исходящего запроса. Эта модель является улучшением по сравнению с добавлением заголовков авторизации вручную в HTTP-запросы по следующим причинам.

  • Обновление токена обрабатывается автоматически. Вам не нужно беспокоиться о просроченных токенах.
  • Токены никогда не хранятся в состоянии устойчивой оркестрации.
  • Вам не нужно писать код для управления получением токена.

Полный пример можно найти в примере precompiled C# RestartVMs.

Управляемые удостоверения не ограничиваются управлением ресурсами в Azure. Управляемые удостоверения можно использовать для доступа к любому API, который принимает токены Microsoft Entra, включая службы Microsoft Azure и веб-приложения от партнеров. Партнерское веб-приложение может даже быть другим приложением-функцией. Список служб Azure от Корпорации Майкрософт, поддерживающих проверку подлинности с помощью Microsoft Entra ID, см. в разделе Azure службы, поддерживающие проверку подлинности Microsoft Entra.

Ограничения

Встроенная поддержка вызова API-интерфейсов HTTP — это вспомогательная функция. Она подходит не для всех сценариев.

HTTP-запросы, отправленные функциями оркестратора, и их ответы сериализуются и сохраняются в качестве сообщений в поставщике хранилища Durable Functions. Это поведение постоянной очереди гарантирует, что HTTP-вызовы являются надежными и безопасными для воспроизведения оркестрации. Однако поведение постоянной очереди также обладает ограничениями.

  • Каждый HTTP-запрос требует дополнительной задержки по сравнению с собственным HTTP-клиентом.
  • В зависимости от настроенного поставщика хранилища крупные сообщения запроса или ответа могут значительно снизить производительность оркестрации. Например, при использовании Azure Storage HTTP-данные, которые слишком велики, чтобы поместиться в сообщения очереди Azure, сжимаются и хранятся в Azure Blob-хранилище.
  • Потоковая передача, фрагментированность и двоичные данные не поддерживаются.
  • Возможность настройки поведения клиента HTTP ограничена.

Если какое-либо из этих ограничений может повлиять на ваш вариант использования, вместо этого следует использовать функции действий и клиентские библиотеки HTTP, зависящие от языка, для выполнения исходящих вызовов HTTP.

Расширяемость (только .NET в процессе)

Настройка поведения внутреннего HTTP-клиента оркестровки возможна с помощью внедрения зависимостей Azure Functions .NET для встроенного рабочего процесса. Эта возможность может быть полезной для внесения небольших изменений в поведение. Она также может быть полезна для модульного тестирования HTTP-клиента путем внедрения макетов объектов.

В следующем примере демонстрируется использование инъекции зависимостей для отключения проверки сертификата TLS/SSL для оркестраторных функций, которые обращаются к внешним HTTP-узлам.

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

Дальнейшие действия