Я исследовал эту проблему и нашел много статей, а также q +, как здесь, но ничего для моего сценария. У меня есть API asp.net core 3 с 2 версиями, 1 и 2. API имеет 3 потребителя, ConA, ConB и ConC, а также 3 контроллера. ConA обращается к контроллерам 1 и 2, ConB обращается только к контроллеру 3, а ConC получает доступ к одной конечной точке от контроллера 1 и одной конечной точке от контроллера 3. Для v1 я показываю все, но теперь у меня есть требование фильтровать конечные точки v2 по потребителю API.
Я пытаюсь создать документ Swagger для каждого потребителя, который показывает только конечные точки, к которым они могут получить доступ. Это легко сделать для ConA и ConB, поскольку я могу использовать [ApiExplorerSettings(GroupName = "v-xyz")]
, где v-xyz может быть ограничен потребителем, а затем таким образом разделить документы Swagger. Проблема заключается в отображении конечных точек для ConC - у них нет собственного контроллера, поэтому я не могу дать им GroupName. Вот упрощенная версия кода:
public void ConfigureServices(IServiceCollection services)
{
services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
});
services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VV";
options.SubstituteApiVersionInUrl = true;
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo() { Title = "My API - Version 1", Version = "v1.0" });
c.SwaggerDoc("v2-conA", new OpenApiInfo() { Title = "My API - Version 2", Version = "v2.0" });
c.SwaggerDoc("v2-conB", new OpenApiInfo() { Title = "My API - Version 2", Version = "v2.0" });
c.SwaggerDoc("v2-conC", new OpenApiInfo() { Title = "My API - Version 2", Version = "v2.0" });
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
c.EnableAnnotations();
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.EnableDeepLinking();
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
c.SwaggerEndpoint("/swagger/v2-conA/swagger.json", "My API V2 ConA");
c.SwaggerEndpoint("/swagger/v2-conB/swagger.json", "My API V2 ConB");
c.SwaggerEndpoint("/swagger/v2-conC/swagger.json", "My API V2 Con3");
});
}
Контроллеры версии 1:
[Route("api/account")]
[ApiController]
[ApiExplorerSettings(GroupName = "v1")]
public class AccountController : ControllerBase
{
[HttpGet("get-user-details")]
public ActionResult GetUserDetails([FromQuery]string userId)
{
return Ok(new { UserId = userId, Name = "John", Surname = "Smith", Version = "V1" });
}
}
[Route("api/account-admin")]
[ApiController]
[ApiExplorerSettings(GroupName = "v1")]
public class AccountAdminController : ControllerBase
{
[HttpPost("verify")]
public ActionResult Verify([FromBody]string userId)
{
return Ok($"{userId} V1");
}
}
[Route("api/notification")]
[ApiController]
[ApiExplorerSettings(GroupName = "v1")]
public class NotificationController : ControllerBase
{
[HttpPost("send-notification")]
public ActionResult SendNotification([FromBody]string userId)
{
return Ok($"{userId} V1");
}
}
Контроллеры версии 2 (в отдельной папке контроллеры / v2):
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/account")]
[ApiController]
[ApiExplorerSettings(GroupName = "v2-conA")]
public class AccountController : ControllerBase
{
[HttpGet("get-user-details")]
[SwaggerOperation(Tags = new[] { "ConA - Account" })]
public ActionResult GetUserDetails([FromQuery]string userId)
{
return Ok($"{userId} V2");
}
}
[Route("api/v{version:apiVersion}/account-admin")]
[ApiController]
[ApiVersion("2.0")]
[ApiExplorerSettings(GroupName = "v2-conB")]
public class AccountAdminController : ControllerBase
{
[HttpPost("verify")]
[SwaggerOperation(Tags = new[] { "ConB - Account Admin", "ConC - Account Admin" })]
public ActionResult Verify([FromBody] string userId)
{
return Ok($"{userId} V2");
}
}
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/notification")]
[ApiController]
[ApiExplorerSettings(GroupName = "v2-conA")]
public class NotificationController : ControllerBase
{
[HttpPost("send-notification")]
[SwaggerOperation(Tags = new[] { "ConA - Notification", "ConC - Notification" })]
public ActionResult SendNotification([FromBody] string userId)
{
return Ok($"{userId} V2");
}
}
Это дает мне возможность увидеть конечные точки для ConA и ConB, хотя это не идеально, поскольку показывает повторяющиеся конечные точки, но я застрял в том, как показать конечные точки для ConC (кто может видеть одну конечную точку с контроллера 1 и один от контроллера 3). Моя следующая попытка будет состоять в том, чтобы вернуться к отображению всех конечных точек в версии 2, а затем выполнить фильтрацию с помощью IDocumentFilter, если я не могу каким-то образом заставить вышеуказанное работать. Любые мысли или советы приветствуются ????