You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add pre-generation OpenAPI hook in AddOpenApi options to initialize document metadata #65723
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.
builder.Services.AddOpenApi(options =>{options.AddPreGenerationDocumentHook((document,context,token)=>{document.Tags??=[];document.Tags.Add(newOpenApiTag{Name="users",Summary="User operations",Description="Endpoints for user lifecycle."// parent/kind when supported by the model});returnTask.CompletedTask;});});
Proposed execution order
Create base document (Info, Servers)
Run pre-generation hook
Generate paths/operations/components
Run existing document transformers
Additional context
This would complement (not replace) AddDocumentTransformer, and improve support for advanced OpenAPI metadata composition.
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.
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.
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.
At the same time, we added IHostedLifecycleService for pre/post start/stop events, so it's not unheard of, for us to add new stages if it's truly useful.
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.
@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:
the middleware is one type, we have 3 transformer types (Document, Operation, Schema).
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:
a hook to initialize the document (pre-generation)
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:
define a single IOpenApiTransformer interface, that ONLY transforms the document
implement the document generation itself as one of those transformers
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.
Activity
baywet commentedon Jun 29, 2026
Just put together #67457
dotnet-policy-service commentedon Jul 20, 2026
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:
Youssef1313 commentedon Jul 20, 2026
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.
halter73 commentedon Jul 20, 2026
API Review Notes:
DocumentTransformersalways run fast, and we want to be able to run them first:IHostedLifecycleServicefor pre/post start/stop events, so it's not unheard of, for us to add new stages if it's truly useful.List<object>and run them in the order they are registered.AddPreGenerationDocumentHookplush more.AppContextswitch could hold people over until they update their code to have the right global ordering.AddTransformeroverloads that you could call instead ofAddSchemaTranformer,AddOperationTransformerorAddDocumentTranformerthat 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 newAddTransformeroverloads fer every registration.baywet commentedon Jul 21, 2026
@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:
If it had been up to me, I'd have designed the whole thing differently:
OR alternatively:
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!