Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting a group name for endpoints and have it be used to populate ApiDescription.GroupName in ApiExplorer for minimal APIs #34541

Closed
Tracked by #34514
DamianEdwards opened this issue Jul 20, 2021 · 1 comment · Fixed by #34906
Assignees
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-minimal-actions Controller-like actions for endpoint routing Priority:1 Work that is critical for the release, but we could probably ship without
Milestone

Comments

@DamianEdwards
Copy link
Member

DamianEdwards commented Jul 20, 2021

APIs described by Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescription can optionally have a group name defined by the GroupName property. Today in the framework there isn't a way provided to set the group name for an endpoint via its metadata and the EndpointMetadataApiDescriptionProvider does not set ApiDescription.GroupName when it populates ApiExplorer with details of the registered endpoints.

ApiDescription.GroupName is used by frameworks like Swashbuckle to associate APIs with different OpenAPI documents, i.e. if the document name and API group name match the API is included in the document (see default logic here).

We should allow for setting the group name for endpoints via their metadata and have that used to populate the ApiDescription.GroupName property when the endpoints are added to ApiExplorer.

Proposed types for addition:

namespace Microsoft.AspNetCore.Routing;

/// <summary>
/// Declares the group name for this endpoint method or delegate.<br />
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
public sealed class EndpointGroupNameAttribute: Attribute, IEndpointGroupNameMetadata
{
    public EndpointGroupNameAttribute(string endpointGroupName)
    {
        if (endpointGroupName == null)
        {
            throw new ArgumentNullException(nameof(endpointGroupName));
        }

        EndpointGroupName = endpointGroupName;
    }

    /// <summary>
    /// The endpoint group name.
    /// </summary>
    public string EndpointGroupName { get; }
}

/// <summary>
/// Specifies an endpoint group name in Microsoft.AspNetCore.Http.Endpoint.Metadata.
/// </summary>
public class EndpointGroupNameMetadata : IEndpointGroupNameMetadata
{
    public EndpointGroupNameMetadata(string endpointGroupName)
    {
        if (endpointGroupName == null)
        {
            throw new ArgumentNullException(nameof(endpointGroupName));
        }

        EndpointGroupName = endpointGroupName;
    }

    /// <summary>
    /// The endpoint group name.
    /// </summary>
    public string EndpointGroupName { get; }
}

/// <summary>
/// Defines a contract use to specify an endpoint group name in Microsoft.AspNetCore.Http.Endpoint.Metadata.
/// </summary>
public interface IEndpointGroupNameMetadata
{
    /// <summary>
    /// The endpoint group name.
    /// </summary>
    string EndpointGroupName { get; }
}

Proposed extension methods for addition:

namespace Microsoft.AspNetCore.Builder;

public static class RoutingEndpointConventionBuilderExtensions
{
+    /// <summary>
+    /// Adds an EndpointGroupNameMetadata item to the Metadata for all endpoints produced by the builder.
+    /// </summary>
+    /// <param name="builder"></param>
+    /// <param name="groupName"></param>
+    /// <returns>The Microsoft.AspNetCore.Builder.IEndpointConventionBuilder.</returns>
+    public static TBuilder WithGroupName<TBuilder>(this TBuilder builder, string groupName) where TBuilder : IEndpointConventionBuilder
+    {
+        builder.WithMetadata(new EndpointGroupNameMetadata(groupName));
+
+        return builder;
+    }
}

Example of these new types and methods being used with minimal APIs:

app.MapGet("/hello/{name}", (string name) => $"Hello {name}")
   .WithName("SayHelloToName")
   .WithGroupName("NameApi")

app.MapGet("/todos/get-all", async (TodoDb db) => await db.Todos.ToListAsync())
   .WithName("GetAllTodos")
   .WithGroupName("TodoApi");
@DamianEdwards DamianEdwards added area-runtime feature-minimal-actions Controller-like actions for endpoint routing labels Jul 20, 2021
@DamianEdwards DamianEdwards changed the title Setting a group name for minimal APIs and having it be used to specify which Open API document the API appears in Allow setting a group name for endpoints and have it be used to populate ApiDescription.GroupName in ApiExplorer for minimal APIs Jul 20, 2021
@ghost
Copy link

ghost commented Jul 20, 2021

Thanks for contacting us.

We're moving this issue to the Next sprint 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.

@rafikiassumani-msft rafikiassumani-msft added the enhancement This issue represents an ask for new feature or an enhancement to an existing one label Jul 20, 2021
@rafikiassumani-msft rafikiassumani-msft added the Priority:1 Work that is critical for the release, but we could probably ship without label Jul 22, 2021
@davidfowl davidfowl added area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels and removed area-runtime labels Jul 31, 2021
captainsafia added a commit that referenced this issue Aug 6, 2021
* Support setting content types in ProducesResponseTypeAttribute to close #34542

* Add WithName extension method to resolve #34538

* Support setting endpoints on group names to resolve #34541

* Add OpenAPI extension methods to resolve #33924

* Add tests for new OpenAPI methods

* Add endpoint metadata attributes

* Update PublicAPI files with deltas

* Add support for SuppressApi to close #34068

* Update tests to account for supporting setting content types

* Fix up PublicAPI analyzer warnings

* Clean up source files

* Address feedback from API review

* Fix typo and update type signature

* Apply feedback from second API review

* Update docstrings

* Apply suggestions from code review

Co-authored-by: Martin Costello <[email protected]>

* Address non-test related feedback

* Handle setting content types for ProducesResponseType attribute

* Address feedback from peer review

* Add test for ProducesResponseType override scenario

Co-authored-by: Martin Costello <[email protected]>
@ghost ghost locked as resolved and limited conversation to collaborators Sep 7, 2021
@amcasey amcasey added the area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc label Jun 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-minimal-actions Controller-like actions for endpoint routing Priority:1 Work that is critical for the release, but we could probably ship without
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants