Skip to content

Add pre-generation OpenAPI hook in AddOpenApi options to initialize document metadata #65723

Description

@baywet

Is there an existing issue for this?

  • I have searched the existing issues

Describe the feature request

Please add a new AddOpenApi options hook that runs before operations/paths are generated, so callers can pre-populate the OpenApiDocument.

Today, AddDocumentTransformer runs after generation, which is too late for some scenarios.

Why this is needed

This would enable setting global tag metadata up front (for example richer Tag Object metadata in OpenAPI 3.2), including fields such as summary/description/parent/kind, then letting
generated operations reference those tags naturally.

Spec reference: https://spec.openapis.org/oas/v3.2.0.html#tag-object

Proposed API shape (example)

   builder.Services.AddOpenApi(options =>
   {
       options.AddPreGenerationDocumentHook((document, context, token) =>
       {
           document.Tags ??= [];
           document.Tags.Add(new OpenApiTag
           {
               Name = "users",
               Summary = "User operations",
               Description = "Endpoints for user lifecycle."
               // parent/kind when supported by the model
           });
           return Task.CompletedTask;
       });
   });

Proposed execution order

  1. Create base document (Info, Servers)
  2. Run pre-generation hook
  3. Generate paths/operations/components
  4. Run existing document transformers

Additional context

This would complement (not replace) AddDocumentTransformer, and improve support for advanced OpenAPI metadata composition.

Activity

  1. added
    needs-area-labelUsed by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically
    on Mar 10, 2026
  2. added
    area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etc
    and removed
    needs-area-labelUsed by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically
    on Mar 10, 2026
  3. added this to the Backlog milestone on Jun 24, 2026
  4. baywet commented on Jun 29, 2026

    @baywet
    ContributorAuthor

    Just put together #67457

  5. self-assigned this
    on Jul 20, 2026
  6. added
    api-ready-for-reviewAPI is ready for formal API review - https://github.com/dotnet/apireviews
    and removed
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Jul 20, 2026
  7. dotnet-policy-service commented on Jul 20, 2026

    @dotnet-policy-service
    Contributor

    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.
  8. Youssef1313 commented on Jul 20, 2026

    @Youssef1313
    Member

    Marking as ready-for-review so I don't loose track for it, but this is likely going to be addressed in .NET 12 and not in .NET 11 due to other priority API reviews.

  9. halter73 commented on Jul 20, 2026

    @halter73
    Member

    API Review Notes:

    • Part of the issue is that DocumentTransformers always run fast, and we want to be able to run them first:
      internal readonly List<IOpenApiDocumentTransformer> DocumentTransformers = [];
      internal readonly List<IOpenApiOperationTransformer> OperationTransformers = [];
      internal readonly List<IOpenApiSchemaTransformer> SchemaTransformers = [];
    • Introducing pipeline stages can be more trouble than it's worth. We used to have lifecycle stages in ASP.NET middleware, and got rid of it and replaced it with a global middleware ordering.
    • Could we just introduce a global ordering? We could store all transformers in an internal List<object> and run them in the order they are registered.
      • Assuming you have fully control over all transformer registrations, this should allow any ordering possible with the proposed AddPreGenerationDocumentHook plush more.
      • This global ordering will be breaking, but how much?
        • Is it few enough an AppContext switch could hold people over until they update their code to have the right global ordering.
        • How many transformers registered today rely on document transformers running before operation transformers running before schema transformers? And how frequently are these registered in an order different than they are expected to be run?
        • This is tough to know, but it could be a lot. In which case we'll have to introduce a new non-breaking API.
        • An alternative might be a new AddTransformer overloads that you could call instead of AddSchemaTranformer, AddOperationTransformer or AddDocumentTranformer that takes any of the three transformer types and opts-in to the global ordering. Transformers using the existing registration APIs could all run before or after this, so long as it's consistent. The idea being that people wanting tight control over the order transformers will run will use the new AddTransformer overloads fer every registration.
  10. added
    api-needs-workAPI needs work before it is approved, it is NOT ready for implementation
    and removed
    api-ready-for-reviewAPI is ready for formal API review - https://github.com/dotnet/apireviews
    on Jul 20, 2026
  11. baywet commented on Jul 21, 2026

    @baywet
    ContributorAuthor

    @halter73 Thanks for the feedback here. Yes, my early career was spent building asp.net webforms components on SharePoint 2007/2010, and the lifecycle aspect was one of the painful aspects....

    I stood up #67925 as a basis for comparison. I'm not super satisfied with it though, the ordering mechanism with your suggestion is a bit of spaghetti code. The change also might surprise people (as demonstrated in the updated unit test). And even ignoring those two aspects for a second, the order changes based on the types of transformers being present. It does feel like a leaky implementation that people will need to understand, that's not a clean "API design".

    If we take your middleware example further, there are a couple of differences:

    1. the middleware is one type, we have 3 transformer types (Document, Operation, Schema).
    2. the core logic IS implemented by a middleware, that makes chaining easier, here we have a separate step to generate the document.

    If it had been up to me, I'd have designed the whole thing differently:

    1. a hook to initialize the document (pre-generation)
    2. accept a set of document walkers (from the OpenAPI.net lib) to apply post-generation transformations (the internal transformations for the schemas being implemented as one)

    OR alternatively:

    1. define a single IOpenApiTransformer interface, that ONLY transforms the document
    2. implement the document generation itself as one of those transformers
    3. let the callers chain things as needed

    Both of those would represent source breaking changes, and require significant rewrites. I'm not sure there's a strong demand for that. Short of this, fixing the current implementation (but in a better way) or introducing a new pre/lifecycle API are probably the cheaper options for everybody involved.

    Let me know what you think!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api-needs-workAPI needs work before it is approved, it is NOT ready for implementationapi-proposalarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions