Skip to content

Add API to support dyanmically generated OpenAPI schemas in document #60589

@captainsafia

Description

@captainsafia

Background and Motivation

The current OpenAPI implementation in ASP.NET Core lacks support for being able to dynamically generate OpenAPI schemas and insert them into the document. Without built-in APIs for this, evelopers must manually write the schemas for types in their application that need to be referenced automatically. While this can be straightforward for simple types, it grows complicated for DTOs and more complex types in the user application. Furthermore, developers can't take advantage of the built-in logic the OpenAPI implementation has to support resolving metadata from ParameterInfo and route constraints.

  • The GetOrCreateSchema API takes a type and an ApiParameterDescription to support being able to generate schemas for the type and apply any metadata from the ParameterInfo to it.
  • The Document property is added to the transformer contexts to allow users to interact with the components store, provided by the underlying Microsoft.OpenApi library.

Proposed API

namespace Microsoft.AspNetCore.OpenApi;

+public interface IOpenApiSchemaProvider
+{
+    OpenApiSchema GetOrCreateSchema(System.Type type, Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterDescription? parameterDescription = null);
+}

public class OpenApiDocumentTransformerContext  : IOpenApiSchemaProvider
{
+    public OpenApiSchema GetOrCreateSchema(System.Type type, Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterDescription? parameterDescription = null);
}

public class OpenApiOperationTransformerContext : IOpenApiSchemaProvider
{
+    public Microsoft.OpenApi.Models.OpenApiDocument Document { get; init; }
+    public OpenApiSchema GetOrCreateSchema(System.Type type, Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterDescription? parameterDescription = null);
}

public class OpenApiSchemaTransformerContext : IOpenApiSchemaProvider
{
+    public Microsoft.OpenApi.Models.OpenApiDocument Document { get; init; }
+    public OpenApiSchema GetOrCreateSchema(System.Type type, Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterDescription? parameterDescription = null);
}

Usage Examples

builder.Services.AddOpenApi("v1", options =>
{
options.AddOperationTransformer((operation, context, cancellationToken) =>
  {      
      // Generate schema for error responses
      var errorSchema = context.GetOrCreateSchema(typeof(ProblemDetails));
      context.Document.AddComponent("Error", errorSchema);
      
      // Reference the schema in responses
      operation.Responses["500"] = new OpenApiResponse
      {
          Description = "Error",
          Content =
          {
              ["application/problem+json"] = new OpenApiMediaType
              {
                  Schema = new OpenApiSchemaReference("Error", context.Document)
              }
          }
      };
      
      return Task.CompletedTask;
  });
});

Alternative Designs

N/A

Design Notes

The IOpenApiSchemaProvider type is not applied on the OpenApiSchemaService registered in the DI container. We opted not to do this in favor of restricting schema generation to the transformer APIs. This avoids the Microsoft.AspNetCore.OpenApi package becoming a generic schema generation API and allows us to limit the functionality to codepaths that we have more control over (OpenAPI document transformers).

Schema transformers registered in an API are applied to schemas that are generated by the service. This can increase the risk for re-entrant or recursive schema transformers to generate too many schemas if developers do not add guards against these cases.

Risks

  1. The new APIs are additions with no breaking changes to existing functionality.
  2. Performance impact should be minimal as schema generation is typically done once during startup or on-demand.
  3. The implementation only exposes APIs for generating schemas, the schema store is modeled directly on the OpenAPI document which is handled by a third-party API.

Metadata

Metadata

Assignees

Labels

api-ready-for-reviewAPI is ready for formal API review - https://github.com/dotnet/apireviewsarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-openapi

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions