ASP.NET Core 6中的AddEndpointsApiExplorer是什么?

61

我正在将一个ASP.NET Core API项目从v5升级到v6。

v5中的服务配置:Swagger中间件添加和配置

services.AddSwaggerGen();

在v6中的服务配置:Swagger中间件添加和配置
builder.Services.AddEndpointsApiExplorer();    // what is this?
builder.Services.AddSwaggerGen();

AddEndpointsApiExplorer是什么?无论我加不加,一切都正常工作。

我使用了“ASP.NET API Versioning”。它们相关吗?如果有关,我必须同时使用两者,只使用库,还是现在库已经不必要了?


我发现了这个链接:https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.endpointmetadataapiexplorerservicecollectionextensions.addendpointsapiexplorer?view=aspnetcore-6.0。 - drum
本教程的来源与发布的文档不同,详见 https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/tutorials/getting-started-with-swashbuckle.md#add-and-configure-swagger-middleware-1。该教程指出,如果您调用 AddMvc,则会为您添加 API Explorer 服务,但最小的 API 设置可能不会被添加。 - Jeremy Lakeman
1
嗯,AddEndpointsApiExplorer是v6中的新功能,其实现与AddApiExplorer略有不同。令人惊讶的是,这个功能没有合并到同一个方法中。它似乎存在的目的是为“Minimal Api”提供端点元数据。https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0 - Jeremy Lakeman
3个回答

68
AddEndpointsApiExplorer 适用于 Minimal APIs,而 AddApiExplorer 至少需要 MVC Core。对于 API 项目,AddControllers 会代表您调用 AddApiExplorer但为什么 AddEndpointsApiExplorer 仍然能正常工作呢? 随着 Endpoint Routing 的引入,路由系统中的所有内容都归结为一个 Endpoint。ASP.NET Core 使用 Application Model(即 ApplicationModelControllerModelActionModel)来创建 Endpoint 实例,并将其注册到路由系统中。然而,Minimal APIs 则使用 builder 直接创建和注册单个的 Endpoint 实例。默认的API浏览器实现提供一个IApiDescriptionProvider,它从应用程序模型构建ApiDescription实例。而Minimal APIs没有应用程序模型,因此无法从中构建ApiDescription实例。API浏览器提供这些描述,通常由OpenAPI生成器等工具使用。如果没有任何描述,就没有对Minimal APIs和OpenAPI的支持,那将是不好的(或者至少肯定不会被开发人员接受)。为了解决这个问题,ASP.NET Core团队创建了第二个IApiDescriptionProvider,它只考虑Endpoint如果一切都是Endpoint,为什么不合并实现?这个答案有两个部分。首先,更改原始的 IApiDescriptionProvider 实现将引入公共的、破坏性的更改。至少需要新的构造函数参数。虽然这是一个主要版本升级,但这种方法实际上并不重要。更大的问题是原始的 IApiDescriptionProvider 实现和 AddApiExplorer 位于并依赖于 MVC Core。而Minimal APIs 只需要路由抽象。没有办法将两者合并而不添加不必要的耦合。为了解决这个问题,添加了 AddEndpointsApiExplorer,它添加了一种只需要基于路由系统的裸骨 Endpoint 定义的 IApiDescriptionProvider 实现。如果 AddEndpointsApiExplorer 已经存在并且我调用了它,那么我是否还需要 AddApiExplorer 呢?也许不需要。在Minimal APIEndpoint实例上公开和可用的元数据比应用程序模型更轻量级;毕竟,它们是minimal的。在幕后,一个IApiDescriptionGroupCollectionProvider实现接受一个IApiDescriptionProvider实例的序列。如果同时调用了AddEndpointsApiExplorerAddApiExplorer,则两个提供程序都会执行。如果只调用AddEndpointsApiExplorer,它将与常规控制器一起工作,但描述信息的准确度可能比您习惯的要低。如果您只编写Minimal API,则如果想要API Explorer支持,就需要使用AddEndpointsApiExplorer

在.NET 7.0中,这两种方法之间的准确度将会进一步提高。在将来的某个版本中,我们有可能会看到这些方法汇合成为一个。


21
TLDR; .AddEndpointsApiExplorer()是为了支持Minimal Api's而创建的。
通过谷歌搜索文档,可以找到很多页面都包含对.AddEndpointsApiExplorer()的调用。但是没有提到你为什么需要它,或者在从v5项目迁移时是否需要它。文档明显缺乏。
从源代码和git blame开始反向工作,我找到了相关项目。因此答案似乎与支持Minimal Api's有关。
我相信一些新服务被创建来从这些新的minimal api中提取返回类型信息,这种方式可能适用于使用Endpoint Routing而不是MVC的更一般的方式。
如果您正在使用MVC,可能通过.AddControllers().AddApiExplorer()将为您调用。提供Swagger所依赖的描述控制器操作的服务。如果这就是你需要的全部,那么这个新的api调用似乎并不是必需的。
虽然使用swagger与minimal api的文档包括对.AddEndpointsApiExplorer()的调用。但即使如此,也没有解释为什么它是必需的。
为什么.AddEndpointsApiExplorer()存在?为什么新功能被排除在.AddApiExplorer()之外?为什么其他v6文档中留下了这个方法的重命名?
也许我们应该在https://github.com/dotnet/aspnetcore/https://github.com/dotnet/AspNetCore.Docs/上创建一个问题,以寻求澄清,这样其他人就不必问这些问题了。

2
谢谢!哇,我希望有一个“代码考古学家”标签,因为这就是你应得的。 :-) 感谢您挖掘这个问题。我已经确认它适用于最小API,如@ChrisMartinez在此处所述。但是来自asp.net方面的问题仍然存在-我会像您建议的那样在文档存储库中创建一个问题。 - lonix
已将问题添加到仓库中。 - lonix
你们打字的速度比我回复的速度还快。=D 下面是详细的解释。如果你真的非常想深入了解,我可以找出在 ASP.NET Core 存储库中发生这些事情的链接。让我知道,我会更新我的答案。希望这能提供一些清晰度。 - Chris Martinez

8

TL;DR

只有在使用v6的“minimal APIs”时才使用AddEndpointsApiExplorer,其外观如下:

app.MapGet("/", () => "Hello World!");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接