自定义 HTTP 命令在 Aspire 中

在Aspire中,可以使用WithHttpCommand API 将自定义 HTTP 命令添加到资源。 此 API 扩展了现有功能,您可以在资源上提供自定义命令。 此功能使资源上的命令能够发送HTTP请求到指定的端点和路径。 这对于某些场景非常有用,例如触发数据库迁移、清理缓存或通过 HTTP 请求对资源执行自定义操作。

要实现自定义 HTTP 命令,您需要在资源上定义一个命令,并设置一个相应的 HTTP 端点来处理请求。 本文概述了如何在其中创建和配置自定义 HTTP 命令 Aspire。

HTTP命令API

可用的 API 提供广泛的功能,并通过众多参数来定制 HTTP 命令。 要向资源添加 HTTP 命令,请在资源构建器上使用 WithHttpCommand 扩展方法。 有两个重载可用:

API WithHttpCommand 提供两个重载,用于向其中 Aspire的资源添加自定义 HTTP 命令。 这些接口旨在提供灵活性并满足定义HTTP命令时的不同用例需求。

  1. 重载:endpointName

    如果具有 HTTP 命令应面向的预定义终结点名称,则此版本是理想的。 通过直接将命令与特定端点关联,它简化了配置过程。 这在终结点在开发过程中是静态的且众所周知的方案中非常有用。

  2. 重载:endpointSelector

    此版本通过允许您指定回调函数 (endpointSelector) 来确定运行时的端点,从而提供了更动态的行为。 当端点可能根据资源的状态或其他上下文因素而变化时,这非常有用。 它为无法将终端硬编码的高级场景提供了更大的灵活性。

两种重载都允许您广泛定制HTTP命令,可以提供HttpCommandOptions类的CommandOptions子类,包括指定HTTP方法、配置请求、处理响应,并定义与UI相关的属性,如显示名称、描述和图标。 这两者之间的选择取决于在您的用例中,终端点是静态的还是动态的。

这些 API 旨在与生态系统无缝 Aspire 集成,使开发人员能够以最少的努力来扩展资源功能,同时保持对命令的行为和呈现的控制。

注册HTTP命令时的注意事项

鉴于HTTP命令通过HTTP端点暴露,需考虑潜在的安全风险。 请在可能的情况下将这些端点限制在开发或预发布环境中。 始终验证传入请求以确保它们来自可信来源。 如需更多信息,请参阅ASP.NET Core安全

使用HttpCommandOptions.PrepareRequest回调,通过添加身份验证头或其他措施来提高安全性。 一种常见方法是使用仅对 AppHost 和资源已知的共享机密、 外部参数或令牌。 此共享值可用于验证请求并防止未经授权的访问。

添加自定义HTTP命令

AppHost.cs文件中,使用WithHttpCommand API 在IResourceBuilder<T>中,其中TIResourceWithEndpoints,添加自定义 HTTP 命令。 这是一个如何做到这一点的例子:

var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

var apiCacheInvalidationKey = builder.AddParameter("ApiCacheInvalidationKey", secret: true);

var api = builder.AddProject<Projects.AspireApp_Api>("api")
    .WithReference(cache)
    .WaitFor(cache)
    .WithEnvironment("ApiCacheInvalidationKey", apiCacheInvalidationKey)
    .WithHttpCommand(
        path: "/cache/invalidate",
        displayName: "Invalidate cache",
        commandOptions: new HttpCommandOptions()
        {
            Description = """            
                Invalidates the API cache. All cached values are cleared!            
                """,
            PrepareRequest = (context) =>
            {
                var key = apiCacheInvalidationKey.Resource.GetValueAsync(context.CancellationToken);

                context.Request.Headers.Add("X-CacheInvalidation-Key", $"Key: {key}");

                return Task.CompletedTask;
            },
            IconName = "DocumentLightning",
            IsHighlighted = true
        });

builder.Build().Run();

前面的代码:

  • 创建新的分布式应用程序生成器。
  • 将名为Redis的添加到应用程序中。
  • 向应用程序添加一个名为ApiCacheInvalidationKey的参数。 此参数被标记为机密,这意味着其值受到安全处理。
  • 向应用程序添加一个名为AspireApp_Api的项目。
  • 将引用添加到Redis缓存,并等待其准备好后再继续
  • 为项目配置具备以下功能的HTTP命令:
    • path:指定 HTTP 命令的 URL 路径(/cache/invalidate)。
    • displayName:设置命令在 UI 中显示的名称(Invalidate cache)。
    • commandOptions:一个可选的HttpCommandOptions实例,用于配置命令在用户界面中的行为和外观。
      • Description:提供关于UI中显示命令的描述。
      • PrepareRequest: 一个在发送之前配置HTTP请求的回调函数。 在这种情况下,它会添加一个具有参数值的X-CacheInvalidation-Key自定义 (ApiCacheInvalidationKey) 标头。
      • IconName:指定在用户界面中用于命令的图标 (DocumentLightningFilled)。
      • IsHighlighted:指示命令在用户界面中是否应该被突出显示。
  • 最后,应用已构建并运行。

HTTP 端点负责无效缓存。 当命令执行时,它会根据配置的参数向指定的路径 (/cache/invalidate) 发送一个 HTTP 请求。 由于增加了安全措施,请求中包含具有X-CacheInvalidation-Key参数值的ApiCacheInvalidationKey标头。 这确保只有获得授权的请求可以触发缓存失效过程。

HTTP 终结点示例

前面的 AppHost 代码片段定义了向终结点发送请求的 /cache/invalidate 自定义 HTTP 命令。 ASP.NET Core 最小 API 项目定义了一个 HTTP 端点来处理缓存失效请求。 请查看项目Program.cs文件中的以下代码片段:

app.MapPost("/cache/invalidate", static async (
    [FromHeader(Name = "X-CacheInvalidation-Key")] string? header,
    ICacheService registry,
    IConfiguration config) =>
{
    var hasValidHeader = config.GetValue<string>("ApiCacheInvalidationKey") is { } key
        && header == $"Key: {key}";

    if (hasValidHeader is false)
    {
        return Results.Unauthorized();
    }

    await registry.ClearAllAsync();

    return Results.Ok();
});

前面的代码:

  • 假设app变量是IApplicationBuilder的一个实例,并设置为处理HTTP请求。
  • 将 HTTP POST 端点映射到路径 /cache/invalidate
  • 终端要求请求中必须包含一个名为 X-CacheInvalidation-Key 的标头。
  • 它从配置中检索 ApiCacheInvalidationKey 参数的值。
  • 如果标头值与预期密钥不匹配,它将返回未经授权的响应。
  • 如果标头有效,它将调用 ClearAllAsync 该方法 ICacheService 以清除所有缓存的项。
  • 最后,它返回 HTTP OK 响应。

仪表板体验示例

示例 AppHost 和相应的 ASP.NET Core 最小 API 项目演示 HTTP 命令实现的两端。 运行 AppHost 时,仪表板的 “资源 ”页将自定义 HTTP 命令显示为按钮。 指定命令应突出显示时(isHighlighted: true),按钮将显示在“资源”页的“作”列中。 这允许用户从仪表板轻松触发命令,如以下屏幕截图所示:

Aspire 仪表板:显示突出显示的自定义 HTTP 命令的资源页。

如果要省略isHighlighted参数或将其false设置为该参数,该命令将显示在“资源”页的“作”列中的水平省略号菜单(三个点)下。 这样,用户就可以访问命令,而不会用太多按钮使 UI 混乱。 以下屏幕截图显示了在省略号菜单中显示的相同命令:

Aspire 仪表板:资源页,其中显示了省略号菜单中的自定义 HTTP 命令。

当用户选择该按钮时,将执行该命令,并将 HTTP 请求发送到指定的终结点。 仪表板提供有关命令的执行状态的反馈,允许用户监视结果。 当程序启动时,会出现一个通知窗口:

Aspire 仪表板:显示自定义 HTTP 命令的 Toast 通知正在启动。

当命令完成时,仪表盘会更新状态,并提供有关其是否成功或失败的反馈。 以下屏幕截图显示了命令的成功执行:

Aspire 仪表板:显示自定义 HTTP 命令成功的 Toast 通知。

另请参阅