在Aspire中,可以使用WithHttpCommand API 将自定义 HTTP 命令添加到资源。 此 API 扩展了现有功能,您可以在资源上提供自定义命令。 此功能使资源上的命令能够发送HTTP请求到指定的端点和路径。 这对于某些场景非常有用,例如触发数据库迁移、清理缓存或通过 HTTP 请求对资源执行自定义操作。
要实现自定义 HTTP 命令,您需要在资源上定义一个命令,并设置一个相应的 HTTP 端点来处理请求。 本文概述了如何在其中创建和配置自定义 HTTP 命令 Aspire。
HTTP命令API
可用的 API 提供广泛的功能,并通过众多参数来定制 HTTP 命令。 要向资源添加 HTTP 命令,请在资源构建器上使用 WithHttpCommand 扩展方法。 有两个重载可用:
API WithHttpCommand 提供两个重载,用于向其中 Aspire的资源添加自定义 HTTP 命令。 这些接口旨在提供灵活性并满足定义HTTP命令时的不同用例需求。
重载:
endpointName如果具有 HTTP 命令应面向的预定义终结点名称,则此版本是理想的。 通过直接将命令与特定端点关联,它简化了配置过程。 这在终结点在开发过程中是静态的且众所周知的方案中非常有用。
重载:
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>中,其中T是IResourceWithEndpoints,添加自定义 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),按钮将显示在“资源”页的“作”列中。 这允许用户从仪表板轻松触发命令,如以下屏幕截图所示:
如果要省略isHighlighted参数或将其false设置为该参数,该命令将显示在“资源”页的“作”列中的水平省略号菜单(三个点)下。 这样,用户就可以访问命令,而不会用太多按钮使 UI 混乱。 以下屏幕截图显示了在省略号菜单中显示的相同命令:
当用户选择该按钮时,将执行该命令,并将 HTTP 请求发送到指定的终结点。 仪表板提供有关命令的执行状态的反馈,允许用户监视结果。 当程序启动时,会出现一个通知窗口:
当命令完成时,仪表盘会更新状态,并提供有关其是否成功或失败的反馈。 以下屏幕截图显示了命令的成功执行: