question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Design: IEndpointConventionBuilder Extensions Unusable By Other Extensions

See original GitHub issue

Background and Motivation

API Versioning has been investigating support for Minimal APIs per dotnet/aspnet-api-versioning#751. In doing so, it has come to light that the extension methods for IEndpointConventionBuilder are inconsistently implemented and many of them have little-to-no usably by other extensions such as API Versioning.

The primary issues relate to OpenApiRouteHandlerBuilderExtensions.cs. These extensions are very likely to be used by customers in conjunction with API Versioning, but cannot be for the following reasons:

  1. RouteHandlerBuilder is sealed
  2. The extensions methods accept and return the concrete RouteHandlerBuilder type

For completeness, a similar problem exists for FallbackEndpointRouteBuilderExtensions.cs. Fallback endpoints are not expected to be used with API Versioning, but it could affect other extensions. These extension methods accept and return IEndpointConventionBuilder, which makes them more usable than OpenApiRouteHandlerBuilderExtensions; however, the lack of passing through a more specific type means that the order setup by developers matters.

The design and implementation of each set of extension methods appears to have been done by different people, at different times, and with different design review considerations.

Proposed API

There doesn’t appear to be a clear reason why these decisions were made. There seems to be no reason to not implement all of the extension methods using the same approach that @JamesNK used in RoutingEndpointConventionBuilderExtensions.cs. This would mean that all extension methods have the form of:

public static TBuilder SomeExtension<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder { } 

This approach appears to have been lightly discussed in #8902 previously, which might explain why future extension methods did not follow suite.

The proposed change would benefit not just API Versioning, but any other extension that needs to add/change significant parts of the default Minimal API implementation.

Risks

Changing the signature of the existing APIs are a breaking change, but I believe that adding the intended generic implementations can live side-by-side with the existing non-generic variants.

If the proposal were accepted, when would that happen? As it stands, this issue cascades across APIs. API Versioning would be required to reimplement all of the applicable, existing extension methods to retain feature parity for non-versioned Minimal APIs. Furthermore, the unnecessary non-generic extensions methods have to be retained just as they do in ASP.NET Core - likely forever more. If API Versioning doesn’t reimplement the extensions methods, then there is a feature gap that must be filled by customers.

API Versioning is looking for guidance to achieve the right level of synergy in both the short and long terms.

Example Usage

The tentative design for Minimal APIs for API Versioning will look something like:

app.DefineApi()
   .HasVersion(1.0)
   .HasVersion(2.0)
   .ReportApiVersions()
   .HasMapping(api => {
       // OpenAPI extensions cannot be used here without reimplementing and maintaining them
   	api.MapGet("/speak", () => "Hello world!");
   	api.MapPost("/speak", (string text) => text).MapToApiVersion(2.0);
   });

cc: @davidfowl @JamesNK

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
halter73commented, Jan 18, 2022

Maybe it’s okay if the existing overloads OpenApiRouteHandlerBuilderExtensions are preferred when given a RouteHandlerBuilder as long as the new overloads also work on any IEndpointConventionBuilder. This means being able to call app.MapHub<MyHub>("/myhub").Accepts<Person>("application/xml") which is weird but perhaps the lesser evil.

0reactions
msftbot[bot]commented, Oct 11, 2022

Thanks for contacting us.

We’re moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it’s very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

Read more comments on GitHub >

github_iconTop Results From Across the Web

David Fowler on Twitter: "Insane 😅 #dotnet #wasi #wasm" / ...
I'm thinking peer to peer web gaming. ... Design: IEndpointConventionBuilder Extensions Unusable By Other Extensions · Issue #39604 ·.
Read more >
C# extension methods design patterns and usage ...
The goal of extension methods is specifically to be able to extend either classes of other assemblies or interfaces.
Read more >
Extensions Module - PJSIP Extension
Overview. This guide walks you through information related to PJSIP extensions. In order to have access to creating PJSIP extensions, ...
Read more >
Extensions of the 2-in-1 adaptive design
We make three major extensions to the 2-in-1 design in this paper: 1) an increase of adaptive decisions from two to any number;...
Read more >
Manage Extensions in ASP.NET Core
Designer module to find extensions used in the Web Dashboard when it operates as a designer. The DevExpress.Dashboard contains extensions used both in ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found