I'm upgrading an ASP.NET Core API project from v5 to v6.
Service config in v5:
services.AddSwaggerGen();
Service config in v6:
builder.Services.AddEndpointsApiExplorer(); // what is this?
builder.Services.AddSwaggerGen();
What is AddEndpointsApiExplorer
? Everything works as expected whether I add it or not.
I use the "ASP.NET API Versioning" library. Are they related? If so, must I use both, just the library, or is the library unnecessary now?
CodePudding user response:
AddEndpointsApiExplorer
is for Minimal APIs whereas AddApiExplorer
requires, at least, MVC Core. For API projects, AddControllers
calls AddApiExplorer
on your behalf.
But Why Does Everything Still Work With AddEndpointsApiExplorer
?
With the introduction of Endpoint Routing, everything in the routing system boils down to an Endpoint
. ASP.NET Core uses the Application Model, namely ApplicationModel
, ControllerModel
, and ActionModel
, to create Endpoint
instances and register them with the routing system. Minimal APIs, however, use a builder to directly create and register individual Endpoint
instances.
The default API Explorer implementation provides a IApiDescriptionProvider
that builds ApiDescription
instances from the Application Model. Minimal APIs do not have an Application Model so there is nothing to build ApiDescription
instances from. The API Explorer provides these descriptions, which are commonly used by tools such as OpenAPI generators. Without any descriptions, there would be no support for Minimal APIs and OpenAPI; that would be bad (or, at least, certainly not accepted by developers). To address that, the ASP.NET Core team created a second IApiDescriptionProvider
that only considers Endpoint
.
If Everything is an Endpoint
, Why Not Merge Implementations?
There's two parts to this answer. First, changing the original IApiDescriptionProvider
implementation would introduce a public, breaking change. At a minimum, new constructor arguments would be required. Since it was a major version bump, this approach wasn't off the table, but it turns out to be irrelevant. The bigger issue is that the original IApiDescriptionProvider
implementation and AddApiExplorer
live in and depend on MVC Core. Minimal APIs only require the routing abstractions. There is no way to merge the two without adding unnecessary coupling. To address this problem, AddEndpointsApiExplorer
was added which adds an implementation that only requires an IApiDescriptionProvider
implementation based on bare bones Endpoint
definitions from the routing system.
If AddEndpointsApiExplorer
exists and I call it, do I even need AddApiExplorer
anymore? Maybe. The metadata exposed and available on Minimal API Endpoint
instances is much lighter than the Application Model; after all, they are minimal. Behind the scenes, a IApiDescriptionGroupCollectionProvider
implementation takes a sequence of IApiDescriptionProvider
instances. If AddEndpointsApiExplorer
and AddApiExplorer
are called, then both providers will execute. If only AddEndpointsApiExplorer
is called, it will work with regular 'ol controllers, but the descriptions' information fidelity might be less than what you are accustomed to. If you are only authoring Minimal APIs, then AddEndpointsApiExplorer
is required if you want API Explorer support.
The fidelity between the two methods is improving even more in .NET 7.0. In some future release, it's possible we might see these approaches coalesce into one.
CodePudding user response:
TLDR; .AddEndpointsApiExplorer()
was created to support Minimal Api's.
Searching the doc's via google shows a number of pages that include a call to .AddEndpointsApiExplorer()
. But no mention of why you need it, or if it is required when migrating from a v5 project. The documentation is definitely lacking.
Working backwards from the source code & git blame, I found the related project. So the answer appears to be related to support for Minimal Api's.
I believe some new services were created to extract return type information from these new minimal api's, in a way that might apply in a more general way when using Endpoint Routing without MVC.
If you are using MVC, perhaps via .AddControllers()
, .AddApiExplorer()
would be called for you. Providing the services that swagger depends on for describing controller actions. If that's all you need, then this new api call doesn't seem to be required.
While the documentation for using swagger with minimal api's includes a call to .AddEndpointsApiExplorer()
. Even that doesn't explain exactly why it is required.
Why does .AddEndpointsApiExplorer()
exist at all? Why were the new features excluded from .AddApiExplorer()
? Why was this method rename left out of other documentation for v6?
Perhaps we should create an issue on https://github.com/dotnet/aspnetcore/ or https://github.com/dotnet/AspNetCore.Docs/ to ask for clarification so that others don't have to ask these questions.