What is AddEndpointsApiExplorer in ASP.NET Core 6
Asked Answered
R

3

74

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?

Rebus answered 20/4, 2022 at 1:4 Comment(3)
I found this learn.microsoft.com/en-us/dotnet/api/…Smelly
The source of this tutorial is different from the published docs github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/… which suggests that if you call AddMvc the api explorer services are added for you, but a minimum api setup may not.Code
Hmmm AddEndpointsApiExplorer is new in v6, the implementation is slightly different to AddApiExplorer. It's surprising that the functionality wasn't merged into the same method. It appears to exist to provide endpoint metadata for "Minimal Api's" learn.microsoft.com/en-us/aspnet/core/fundamentals/…Code
S
85

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're 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.

Stillness answered 20/4, 2022 at 2:47 Comment(0)
C
25

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.

Code answered 20/4, 2022 at 2:2 Comment(3)
Thanks! Wow I wish there were a "code archaeologist" tag, because that's what you deserve. :-) Thanks for digging into this. It's definitely for minimal APIs, I confirmed with @ChrisMartinez here. But the issues from the asp.net side are still there - I'll create an issue on the docs repo as you suggested.Rebus
Added issue to repo.Rebus
You guys are typing faster than I can respond. =D Comprehensive explanation below. If you really, really want to go down the rabbit hole, I can dig up the links in the ASP.NET Core repo where these things happen. Let me know and I'll update my answer. Hopefully, that provides some clarity.Stillness
R
10

TL;DR

Only use AddEndpointsApiExplorer if you use v6's "minimal APIs", which look like this:

app.MapGet("/", () => "Hello World!");
Rebus answered 20/4, 2022 at 8:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.