在开发Web应用程序时,REST API端点的管理是一个重要的环节。随着应用程序的增长,端点数量可能会迅速增加,这可能会导致用户界面(UI)变得杂乱无章。为了优化用户体验和开发效率,可以通过配置文件来控制哪些端点对用户可见,哪些不可见。本文将介绍如何实现这一功能。
隐藏端点并不意味着它不可用,REST客户端仍然可以无限制地使用这些端点。隐藏端点主要是为了UI的整洁和开发过程中的优化。例如,在开发模式下,可能希望隐藏一些用于审计或特定集成级别的端点,以减少启动时的加载时间和UI的复杂性。
端点的可见性是通过应用程序配置文件中的设置来定义的。以下是一个配置文件的例子,它定义了哪些端点是可见的,哪些是不可见的。
{
"ApiConfiguration": {
"VisibleItems": [
"User.*",
"WeatherForecast.Get*"
],
"HiddenItems": [
"User.*",
"WeatherForecast.DeleteWeatherForecast"
]
}
}
在这个例子中,"VisibleItems"定义了所有用户相关的端点和WeatherForecast控制器中以Get开头的操作都是可见的。而"HiddenItems"定义了所有用户相关的端点和WeatherForecast控制器中的DeleteWeatherForecast操作是不可见的。
ASP.NET Core提供了一个名为ActionModelConvention的机制,可以用来定义端点的可见性。可以通过实现ApiVisibilityConvention类来控制端点的显示与隐藏。
internal sealed class ApiVisibilityConvention : IActionModelConvention
{
private List<string> VisibleItems { get; }
private List<string> HiddenItems { get; }
internal ApiVisibilityConvention(IEnumerable<string>? visibleItems = null, IEnumerable<string>? hiddenItems = null)
{
VisibleItems = visibleItems != null ? new List<string>(visibleItems) : new List<string>();
HiddenItems = hiddenItems != null ? new List<string>(hiddenItems) : new List<string>();
}
public void Apply(ActionModel action)
{
// 可见性逻辑
if (VisibleItems.Count > 0)
{
action.ApiExplorer.IsVisible = VisibleItems.Any(x => MatchItem(action.Controller.ControllerName, GetOperationId(action), x));
}
if (HiddenItems.Count > 0)
{
if (VisibleItems.Count > 0)
{
action.ApiExplorer.IsVisible = !HiddenItems.Any(x => MatchItem(action.Controller.ControllerName, GetOperationId(action), x));
}
else
{
action.ApiExplorer.IsVisible = !HiddenItems.Any(x => MatchItem(action.Controller.ControllerName, GetOperationId(action), x));
}
}
}
private static string? GetOperationId(ActionModel action) =>
(action.Attributes.FirstOrDefault(x => x is HttpMethodAttribute) as HttpMethodAttribute)?.Name;
private static bool MatchItem(string controllerName, string? operationId, string mask)
{
// 匹配逻辑
}
private static bool MatchExpression(string text, string expression)
{
// 正则表达式匹配逻辑
}
}
在程序启动时,会从配置文件中读取端点过滤器,并在添加控制器时注册ApiVisibilityConvention。
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
IConfiguration Configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
var apiConfiguration = Configuration.GetSection(nameof(ApiConfiguration)).Get<ApiConfiguration>();
builder.Services.AddControllers(setupAction =>
{
if (apiConfiguration != null)
{
setupAction.Conventions.Add(new ApiVisibilityConvention(apiConfiguration.VisibleItems, apiConfiguration.HiddenItems));
}
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(setupAction =>
{
setupAction.DisplayOperationId();
});
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}