Skip to content

Introduce Microsoft.AspNetCore.OpenApi package #40676

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

Closed
DamianEdwards opened this issue Mar 12, 2022 · 12 comments · Fixed by #41238
Closed

Introduce Microsoft.AspNetCore.OpenApi package #40676

DamianEdwards opened this issue Mar 12, 2022 · 12 comments · Fixed by #41238
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc 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 feature-openapi old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Milestone

Comments

@DamianEdwards
Copy link
Member

Consider introducing a new package Microsoft.AspNetCore.OpenApi that provides integration features for ASP.NET Core HTTP APIs and OpenAPI. This package takes a dependency on Microsoft.OpenApi and contains the logic that maps primitive ASP.NET Core endpoint details to representations in endpoint metadata using the object model provided by Microsoft.OpenApi, along with projecting these details into the legacy ApiExplorer API from MVC. Furthermore, it provides helper methods for easily adding user-specified OpenAPI relevant details directly to endpoint metadata.

This would essentially be a strategy shift so that instead of continuing to add more metadata types to the framework to allow more details about endpoint APIs to be declared and published in MVC's ApiExplorer (e.g. #40084), we embrace the existing OpenAPI object model in Microsoft.OpenApi and allow all operation details to be specified in an endpoint's metadata and projected into ApiExplorer so that existing libraries like Swashbuckle continue to work.

The package would do the following:

  • Depend on Microsoft.OpenApi
  • Contain the logic that maps the MethodInfo for a route handler delegate in the endpoint metadata, to the requisite Microsoft.OpenApi.Models.OpenApiOperation
  • Provide extension methods to easily allow mutating a route handler delegate's OpenApi metadata, e.g.
    app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
        .WithOpenApiDetails(operation =>
        {
            operation.OperationId = "GetAllTodos";
            operation.Description = "This API returns all the Todos.";
        });
  • Preserves the Microsoft.OpenApi.Models.OpenApiOperation in the endpoint metadata
    • This requires a new extensibility point be added such that the package can mutate the metadata for endpoints built by the route endpoint builder
  • Contain the IApiDescriptionProvider that projects a route handler's details from its OpenAPI endpoint metadata into ApiExplorer
  • Be referenced in the Web API project template
  • Would not reference Swashbuckle.AspNetCore, rather a project would still need to reference the SwaggerUI/OpenAPI library it wishes to use and call the requisite configuration methods for it to be configured

We need to consider of course how we do this without breaking (too much) stuff. In .NET 6, Minimal API endpoints are added to the ApiExplorer if MVC is configured, or the AddEndpointsApiExplorer() services extension method is called.

@DamianEdwards DamianEdwards added enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-openapi feature-minimal-actions Controller-like actions for endpoint routing old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels labels Mar 12, 2022
@davidfowl
Copy link
Member

cc @darrelmiller @bradygaster

@bradygaster
Copy link
Member

i really like this idea.

@bradygaster
Copy link
Member

Also DM's library can translate betwixt versions of OpenAPI (and output format - YAML/JSON). We could use that.

@darrelmiller
Copy link

Sign us up.

@rafikiassumani-msft rafikiassumani-msft added this to the .NET 7 Planning milestone Mar 15, 2022
@ghost
Copy link

ghost commented Mar 15, 2022

Thanks for contacting us.

We're moving this issue to the .NET 7 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 Needs: Design This issue requires design work before implementating. label Mar 15, 2022
@dosper7
Copy link

dosper7 commented Apr 1, 2022

I'm sold 🤑 really like this one.

@jchannon
Copy link
Contributor

jchannon commented Apr 7, 2022

giphy

@captainsafia
Copy link
Member

captainsafia commented Apr 15, 2022

Proposed API

namespace Microsoft.AspNetCore.OpenApi;

public static class OpenApiRouteHandlerBuilderExtensions
{
  public static RouteHandlerBuilder WithApiDescription(
    this RouteHandlerBuilder builder,
    Action<OpenApiPathItem>? configureDescription = null) { }
}
public static class OpenApiServicesExtensions
{
  public static IServiceCollection AddOpenApiGenerator(this IServiceCollection services) {}
}
public class OpenApiGenerator
{
  public OpenApiGenerator(
        IHostEnvironment? environment,
        IServiceProviderIsService? serviceProviderIsService) { }
}
namespace Microsoft.AspNetCore.Mvc;

public class ProducesResponseTypeAttribute : Attribute, IApiResponseMetadataProvider
{
-  internal bool IsResponseTypeSetByDefault { get; }
+  public bool IsResponseTypeSetByDefault { get; }
}

Usage Examples

var builder = WebApplication.CreateBuilder();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApiGenerator();

var app = builder.Build();

app.MapGet("/todo/{id}", (int id) => {})
.WithApiDescription(desc => {
  desc.Operations[OperationType.Get].Summary = "Get a Todo by ID";
  desc.Operations[OperationType.Get].Parameters[0].Summary = "The ID associated with the Todo";
  desc.Operations[OperationType.Get].Parameters[0].Required = true;
});

@captainsafia captainsafia added api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews and removed Needs: Design This issue requires design work before implementating. labels Apr 15, 2022
@ghost
Copy link

ghost commented Apr 15, 2022

Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:

  • The PR contains changes to the reference-assembly that describe the API change. Or, you have included a snippet of reference-assembly-style code that illustrates the API change.
  • The PR describes the impact to users, both positive (useful new APIs) and negative (breaking changes).
  • Someone is assigned to "champion" this change in the meeting, and they understand the impact and design of the change.

@DamianEdwards
Copy link
Member Author

Some alternatives for AddOpenApiGenerator:

  • AddOpenApiEndpoints
  • AddOpenApiEndpointMetadata
  • AddOpenApi

@captainsafia
Copy link
Member

captainsafia commented Apr 15, 2022

Note: WithApiDescription should change naming and input parameter.

WithOpenApi();
WithOpenApi(Func<OpenApiOperation, OpenApiOperation> produceOperation);

Remove:

public static IServiceCollection AddOpenApiGenerator(this IServiceCollection services) {}

Make this type internal:

internal class OpenApiGenerator
{
  internal OpenApiGenerator(
        IHostEnvironment? environment,
        IServiceProviderIsService? serviceProviderIsService) { }
}

@halter73
Copy link
Member

API Review Notes:

using Microsoft.AspNetCore.OpenApi;

// ...

app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        OperationId = "GetAllTodos",
        Description = "This API returns all the Todos.",
    })
  • Are we worried about the extensibility of OpenApiOperation since we do not own the type? No. We can lean on the OpenApiOperation.Extensions dictionary if we really must.

Final approved API:

+ namespace Microsoft.AspNetCore.OpenApi;
+
+ public static class OpenApiRouteHandlerBuilderExtensions
+ {
+   public static RouteHandlerBuilder WithOpenApi(this RouteHandlerBuilder builder)
+   public static RouteHandlerBuilder WithOpenApi(this RouteHandlerBuilder builder, Func<OpenApiOperation, OpenApiOperation> configureOperation)
+ }

namespace Microsoft.AspNetCore.Builder;

public abstract class EndpointBuilder
{
+  public IServiceProvider? ServiceProvider { get; set; }
}

@halter73 halter73 added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews labels Apr 19, 2022
@ghost ghost locked as resolved and limited conversation to collaborators May 19, 2022
@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
api-approved API was approved in API review, it can be implemented area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc 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 feature-openapi old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Projects
None yet
10 participants