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

Support XML-based OpenAPI docs for minimal and controller-based APIs with Microsoft.AspNetCore.OpenApi #39927

Closed
1 task done
Tracked by #59443
captainsafia opened this issue Feb 1, 2022 · 26 comments
Assignees
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-minimal-actions Controller-like actions for endpoint routing feature-openapi
Milestone

Comments

@captainsafia
Copy link
Member

captainsafia commented Feb 1, 2022

This issue tracks adding support for enhancing OpenAPI documents generated via the Microsoft.AspNetCore.OpenApi package with XML comments present in both minimal and controller-based APIs and their shared types.

Development for this is happening in preview over in the AspLabs repo in this directory but issues and discussions will happen here.

Eventually, the goal is to stabilize this source generator implementation then fold it into the Microsoft.AspNetCoreOpenApi. Tangentially, there's a soft goal to split out some of the logic for processing XML doc comments into structured metadata via Roslyn analysis into a separate package.

Update from October 26th, 2024:

I've snapped out preview bits of XML support for both Minimal APIs + controller-based APIs out of the AspLabs repo. For now, this package is being shipping in preview out of the dotnet10 package feeds.

$ dotnet new webapi
$ dotnet new nugetconfig
$ dotnet nuget add source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json -n dotnet10
$ dotnet add package Microsoft.AspNetCore.OpenApi.SourceGenerators --prerelease

Currently, he functionality is on-by-default so once you add the package reference above you'll see annotations light up. No modifications to any code are necessary.

Some limitations, caveats, and notes:

  • This package assumes that you are using Microsoft.AspNetCore.OpenApi to generate your OpenAPI documents. Under the hood, it's using the transformer APIs in this package to apply the docs.
  • This package currently only applies XML docs in the application assembly. External references aren't supported. Apparently, there's some fussing about with MSBuild (and possibly the compiler) to get XML files associated with external references loaded smoothly.
  • There isn't super great support for crefs as mentioned in the comment above but this is something I hope to tackle before we ship the package inside Microsoft.AspnetCore.OpenApi for v10.

I've created a branch in the TrainingApi sample app to showcase the current state of the package. You can find that sample over https://github.com/captainsafia/TrainingApi/tree/safia/xml-support.


Open me for old issue content

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Swashbuckle currently supports reading the XML doc string associated with an action's method to derive the description, summary, example, etc for an action.

We need to add similar support for minimal endpoints where the documentation might be on a referenced method group or (maybe) on a Map* invocation.

Expected Behavior

/// <summary>
/// This is a foo.
/// </summary>
string GetFoo() => "This is a test";

Should resolve the correct summary info.

@captainsafia captainsafia added old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels feature-minimal-actions Controller-like actions for endpoint routing feature-openapi labels Feb 1, 2022
@rafikiassumani-msft rafikiassumani-msft added this to the .NET 7 Planning milestone Feb 1, 2022
@ghost
Copy link

ghost commented Feb 1, 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.

@jvetter713
Copy link

I feel this is a very important feature. Minimal Web API's are awesome but if we cannot use comments for use with Swagger, they lose their appeal. Please make this happen.

@LeoJHarris
Copy link

Make minimal API's even better with comments 👍 must have feature.

@mholec
Copy link

mholec commented May 31, 2022

I consider this functionality unnecessary. Given the way REST APIs are created and the constant proliferation of approaches like microservices and API gateways, generating documentation in general makes no sense. The documentation generated falls short of the quality of the specification and reflects implementation errors. Generated documentation is unusable in practice for automation, mocking and testing. The specification first approach has been a trend for several years.

@t4apps
Copy link

t4apps commented Jul 6, 2022

The Open API documentation can be imported directly into Azure APIM (public facing). It makes a lot of sense.

@andrewlock
Copy link
Contributor

Just FYI, this already works, as long as you

  • Setup Documentation generation
  • Configure IncludeXmlComments in AddSwaggerGen()
  • Use MethodGroup endpoint handlers.

That last point is the biggest sticking point - it would be great if you could use lambdas too, but at least this partially works 🙂

One observation (I'm not sure if it's a bug or expected behaviour). If you use WithOpenApi(), it wipes out any existing documentation of the parameters that comes from XML

@ghost
Copy link

ghost commented Oct 11, 2022

Thanks for contacting us.

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

@JHorvath-MaxetaTech
Copy link

As far as feedback goes, 100% yes please implement this. We just started to move all our old Controller based APIs to new Minimal APIs and immediately realized none of the documentation was coming across in the swagger page. HUGE let-down! This is super important for public facing APIs, allowing developers to easily understand and consume REST services without the need for separate documentation.

@pepperpark
Copy link

Thanks for contacting us.

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

Five more comments and it will be moved to the .NET 9 Planning? :-D

@captainsafia
Copy link
Member Author

Five more comments and it will be moved to the .NET 9 Planning? :-D

lol trust me i feel this way about some favorite issues of mine too

To provide some more context here, at the moment, support for XML docs in OpenAPI isn't supported in-framework by ASP.NET. Instead, you're probably getting the functionality from whatever package you're using to render the Swagger UI and produce the OpenAPI JSON/YML document (usually NSwag or Swashbuckle for most people).

This issue is tracking making integration of XML docs automatic for minimal APIs that leverage WithOpenApi. It falls into the category of features like #44232 and #39761 where the goal is to make sure that more concepts from your code get funneled into OpenAPI documentation without you having to interfere as much (e.g. enable XML integration in options or document the OpenAPI security definitions yourself).

This feature has a lot of up-votes, which is one of the indicators we use for prioritization (see the docs on how we do milestone planning).

So if these types of features will be helpful to you, giving the main issue an upvote is a great way to help identify which issues are important. Especially for OpenAPI, where TBH, there's a lot of L-XL sized issues that are one our bucket list.

LMK if you have any other feedback/questions.

BTW: I have made of prototype of built-in XML support so there has been some effort applied in this area already.

@MNF
Copy link

MNF commented Mar 20, 2023

@andrewlock, could you please point to an example where minimal api generates swagger including xml comments?

@captainsafia
Copy link
Member Author

@Lonli-Lokli It looks like the example that you provided showcases OpenAPI + Minimal API + API versioning. This blog post summarizes the XML-specific stuff.

@amcasey amcasey added the area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc label Jun 2, 2023
@captainsafia captainsafia removed the old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels label Jun 6, 2023
@captainsafia
Copy link
Member Author

captainsafia commented Jul 17, 2024

Hi all!

I wanted to share some updates in this workstream as we get closer to .NET 9 RCs and beyond. Here's the TL;DR:

  • The good news: I've landed on a design for this feature that addresses our main priorities for this stream of work (native AoT-compat, perf, accuracy)
  • The bad news: This will not ship in GA quality for .NET 9.

The extended edition for those who care about it:

The long-term plan at the moment is to ship a source generator in-the-box with Microsoft.AspNetCore.OpenApi that statically analyzes the code for XML comments at build-time and emits a IOpenApiTransformer definitions to the compilation that apply these discovered annotations to the document model.

Doing the discovery work at compile-time allows us to take advantage of pre-existing APIs in Roslyn and in DocFX for discovering XML comments and mapping them to types which lends itself well to accuracy/completeness in the model since these APIs have had some battle-testing in the form of their integrations in Visual Studio QuickInfo and the .NET API docs on docs.microsoft.com.

As for the delay in release, I want to take some time to polish the implementation instead of rushing to ship something in .NET 9 GA that will be incomplete/not land well.

My plan at the moment is to ship a preview-level package of the XML support out of the AspLabs repo for .NET 9 and target this for official release as part of .NET 10. I think this strikes a good balance between giving those eager to try the feature the change to take advantage of it in .NET 9 and gives more bandwith to iterate and land on the right thing for an LTS release.

So yeah....I wish I had better news to share 😅 but I hope this helps us make progress towards resolving this long-standing feature request once and for all.

If you have any questions about the implementation details, let me know. I hope to get the preview code out once action on the main Microsoft.AspNetCore.OpenApi work has slowed.

@bkoelman
Copy link

The long-term plan at the moment is to ship a source generator in-the-box...

What's great about ASP.NET is that many built-in framework components/services can be replaced with custom implementations, which is what third-party libraries are doing all the time. As a result, a rich ecosystem has emerged. The new OpenAPI integration in ASP.NET doesn't adhere to that design philosophy. Instead of being able to plug in alternate implementations, all that's provided are "fix-up-afterwards" extensibility points (the transformers). Solutions like this paint third-party and framework developers into a corner: instead of plugging in customized behavior, they need to implement additional components that first "undo" the built-in behaviors at runtime and then recreate or fix things up as needed. That's brittle and kills performance.

And using a source generator, as proposed here, makes it impossible to customize the experience (because source generators can't depend on other source generators, and third-party renderers can no longer depend on runtime information). This isn't good enough. NSwag and Swashbuckle are widely used because they're very extensible and customizable. Instead of using a source generator, the tooling should scan the assembly.xml file and populate ApiExplorer, which would enable third-party libraries to integrate.

@captainsafia
Copy link
Member Author

Instead of being able to plug in alternate implementations

I think it depends on what you mean by alternate implementations here...

The goal of the OpenAPI integration is to present information that ASP.NET Core understands about the binding/response serialization behavior of APIs in an application in a way that is compliant with the OpenAPI spec.

In that sense, its purely a presentation layer and the things you want to extend/customize are the framework abstractions that end up influencing the binding/metadata rules (IEndpointMetadataProvider, InputFormatter, OutputFormatter, etc.)

And using a source generator, as proposed here, makes it impossible to customize the experience (because source generators can't depend on other source generators, and third-party renderers can no longer depend on runtime information).

What kind of customizations to the XML documentation implementation are you looking to make/influence?

the tooling should scan the assembly.xml file and populate ApiExplorer, which would enable third-party libraries to integrate.

ApiExplorer is the abstraction layer that allows framework implementations to describe the parameter binding and response serialization behavior of their implementation, which ends up influencing the resulting Open API document. ApiExplorer isn't the abstraction layer for exposing information that is actually inert to the behavior of the framework. For example, endpoint descriptions and tags are represented using endpoint metadata, and not as first-class properties in ApiExplorer for this very reason.

Now, there's a separate discussion to be had about whether or not it makes sense to expose the information derived XML docs on types via the source generator in some other runtime API, but I'm not convinced that ASP.NET Core is the right place for an abstraction like that given it has no direct relationship to web APIs.

@bkoelman
Copy link

I realize using ApiExplorer is not the right terminology. Instead, I should have referred to MVC-based extensibility such as IEndpointMetadataProvider. That's where I'd like the documentation to end up. So that a custom IActionDescriptorCollectionProvider can modify it.

The thing is that summary and description in OpenAPI are the places to express human-friendly information that can't be expressed in the OAS structure itself. The use of .NET attributes enable API developers to indicate intent. From those, documentation can be generated to make API consumers aware of how to use it. Examples:

  • [UsesCursorPagination]: "This endpoint uses cursor pagination. The next link represents a snapshot that expires in 2 minutes."
  • [ExpiresAt("2025-01-01", "GetBasketSummary")]: "This endpoint is deprecated and will be taken offline at 2025-01-01. Use the GetBasketSummary endpoint instead."
  • [RequiresAdmin]: "This endpoint is only accessible to admin users. See {link} on how to request access."
  • [IsExperimental]: "This endpoint is experimental and may be changed in the future."
  • [RateLimited(RateLimitLevel.Medium)]: "A rate limit of 30 requests per 5 minutes applies to this endpoint."
  • [AllowQuery(QueryParameter.Filter | QueryParameter.Sort)]: "This endpoint can be used with the filter and sort query string parameters. See {link} for details."

What's the objection against ASP.NET storing XML doc-comments in the endpoint descriptions, instead of emitting source code?

If the source generator is going to stay, is there a way for a library to deactivate it?

@PaulVrugt
Copy link

Hi all!

I wanted to share some updates in this workstream as we get closer to .NET 9 RCs and beyond. Here's the TL;DR:

  • The good news: I've landed on a design for this feature that addresses our main priorities for this stream of work (native AoT-compat, perf, accuracy)
  • The bad news: This will not ship in GA quality for .NET 9.

The extended edition for those who care about it:

The long-term plan at the moment is to ship a source generator in-the-box with Microsoft.AspNetCore.OpenApi that statically analyzes the code for XML comments at build-time and emits a IOpenApiTransformer definitions to the compilation that apply these discovered annotations to the document model.

Doing the discovery work at compile-time allows us to take advantage of pre-existing APIs in Roslyn and in DocFX for discovering XML comments and mapping them to types which lends itself well to accuracy/completeness in the model since these APIs have had some battle-testing in the form of their integrations in Visual Studio QuickInfo and the .NET API docs on docs.microsoft.com.

As for the delay in release, I want to take some time to polish the implementation instead of rushing to ship something in .NET 9 GA that will be incomplete/not land well.

My plan at the moment is to ship a preview-level package of the XML support out of the AspLabs repo for .NET 9 and target this for official release as part of .NET 10. I think this strikes a good balance between giving those eager to try the feature the change to take advantage of it in .NET 9 and gives more bandwith to iterate and land on the right thing for an LTS release.

So yeah....I wish I had better news to share 😅 but I hope this helps us make progress towards resolving this long-standing feature request once and for all.

If you have any questions about the implementation details, let me know. I hope to get the preview code out once action on the main Microsoft.AspNetCore.OpenApi work has slowed.

I'm a bit confused. Is this support that is not shipping with .net 9 specifically for minimal api's? Or does the openapi generator in .net 9 (the Microsoft.AspNetCore.OpenApi package) not support xml comments from controller methods either? Or does this post have nothing to do with Microsoft.AspNetCore.OpenApi? There are several youtube clips and blogs around stating the new Microsoft.AspNetCore.OpenApi in .net 9 doesn't have xml comment support using this specific comment as a source. But I'm struggling to understand if this is also the case for controller based api's

@mikekistler mikekistler changed the title Support XML-based OpenAPI docs for minimal APIs Support XML-based OpenAPI docs for minimal APIs and MVC Apps Oct 1, 2024
@mikekistler mikekistler added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Oct 1, 2024
@mikekistler mikekistler modified the milestones: 9.0.0, .NET 10 Planning Oct 1, 2024
@captainsafia
Copy link
Member Author

I'm a bit confused. Is this support that is not shipping with .net 9 specifically for minimal api's? Or does the openapi generator in .net 9 (the Microsoft.AspNetCore.OpenApi package) not support xml comments from controller methods either? Or does this post have nothing to do with Microsoft.AspNetCore.OpenApi?

Yes, this is a constraint for controller-based APIs as well....

.....BUT....

I've snapped out preview bits of XML support for both Minimal APIs + controller-based APIs out of the AspLabs repo. For now, this package is being shipping in preview out of the dotnet10 package feeds.

$ dotnet new webapi
$ dotnet new nugetconfig
$ dotnet nuget add source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10/nuget/v3/index.json -n dotnet10
$ dotnet add package Microsoft.AspNetCore.OpenApi.SourceGenerators --prerelease

Currently, he functionality is on-by-default so once you add the package reference above you'll see annotations light up. No modifications to any code are necessary.

Some limitations, caveats, and notes:

  • This package assumes that you are using Microsoft.AspNetCore.OpenApi to generate your OpenAPI documents. Under the hood, it's using the transformer APIs in this package to apply the docs.
  • This package currently only applies XML docs in the application assembly. External references aren't supported. Apparently, there's some fussing about with MSBuild (and possibly the compiler) to get XML files associated with external references loaded smoothly.
  • There isn't super great support for crefs as mentioned in the comment above but this is something I hope to tackle before we ship the package inside Microsoft.AspnetCore.OpenApi for v10.

I've created a branch in the TrainingApi sample app to showcase the current state of the package. You can find that sample over https://github.com/captainsafia/TrainingApi/tree/safia/xml-support.

I'll update the main description of the issue with these details and more now that we've got something going here.

@captainsafia captainsafia changed the title Support XML-based OpenAPI docs for minimal APIs and MVC Apps Support XML-based OpenAPI docs for minimal and controller-based APIs with Microsoft.AspNetCore.OpenApi Oct 26, 2024
@captainsafia captainsafia self-assigned this Oct 26, 2024
@bkoelman
Copy link

@martincostello (co-author of Swashbuckle) built an awesome library at https://github.com/martincostello/openapi-extensions that fills the gap for several missing key pieces in Microsoft.AspNetCore.OpenApi v9. It is AOT-compatible and includes support for XML documentation comments the way I imagined it could be implemented: by reading from the rich ApiDescription/EndpointMetadata at runtime instead of using a source generator. Its approach provides full extensibility to third-party code to influence how documentation ends up in the openapi.json file, leveraging the existing building blocks in ASP.NET.

Please drop the non-extensible source generator effort proposed here in favor of how the openapi-extensions library works. Its implementation is clean and straightforward, doesn't require copied-in sources from other projects, and doesn't have to deal with quirks in MSBuild to load assembly.xml files for referenced assemblies.

To put this in perspective: I'm not concerned if rendering the openapi.json document would take a little bit of time at runtime, because it happens sporadically compared to hitting actual API endpoints. Users who care about extreme performance can render the file at compile-time using Microsoft.Extensions.ApiDescription.Server, or use output caching. What does matter to me is that source generators are being added more and more, which increases build time, severely degrading the inner loop experience in large projects. While the JIT compiler is extremely optimized, the C# compiler hardly does optimizations (by design), so pushing the burden to C# seems counter-productive, especially for API projects with a potentially large number of endpoints.

@captainsafia
Copy link
Member Author

includes support for XML documentation comments the way I imagined it could be implemented: by reading from the rich ApiDescription/EndpointMetadata at runtime

This is incorrect. It doesn't read XML docs from ApiDescriptions, it reads and parses the XML file from disk directly (ref).

instead of using a source generator. Its approach provides full extensibility to third-party code to influence how documentation ends up in the openapi.json file

What extensibility is provided here? Can you show me the code that you would write to get the extensibility that you need?

leveraging the existing building blocks in ASP.NET.

Yes, that's because it uses transformer and ApiExplorer metadata, which is the same approach that a source generator-based implementation would be based on. With that in mind...

Please drop the non-extensible source generator effort proposed here in favor of how the openapi-extensions library works.

You've not clarified how a source generator makes the implementation non-extensible by default or what kind of extensibility you care about. In this comment, you stated that you want to be able to access XML docs in the EndpointDescriptions. The package you referenced doesn't provide this extensibility either. It sets the XML information directly in the OpenAPI document using transformers, using the same extensibility strategy that the source generator-based approach uses.

Its implementation is clean and straightforward, doesn't require copied-in sources from other projects, and doesn't have to deal with quirks in MSBuild to load assembly.xml files for referenced assemblies.

What aspects of a source generator-based approach make any of these things impossible?

What does matter to me is that source generators are being added more and more, which increases build time, severely degrading the inner loop experience in large projects.

This concern is completely separate from the discussion here. Code with poor performance characteristics is not exclusive to source generators and the assumption that just because something is implemented as a source generator it has inherently poor performance characteristics is invalid.

In this comment, I shared the main value prop of using a Roslyn-based approach which is taking advantage of code reuse for existing XML doc handling in the the compiler.

@bkoelman
Copy link

bkoelman commented Nov 20, 2024

includes support for XML documentation comments the way I imagined it could be implemented: by reading from the rich ApiDescription/EndpointMetadata at runtime

This is incorrect. It doesn't read XML docs from ApiDescriptions, it reads and parses the XML file from disk directly (ref).

Agreed. I must have overlooked that part. That's a pity. It does however add action method descriptions to the metadata:

Image

This enables third-party code to modify these descriptions, which is what we need. It would be great if the same were done for doc-comments, but unfortunately, that's not currently the case. If similar attributes for models and their members were defined and ended up in the metadata (produced from assembly.xml or a source generator), third-party code could intercept there, leaving the existing translation from metadata to OpenAPI intact without intervention.

instead of using a source generator. Its approach provides full extensibility to third-party code to influence how documentation ends up in the openapi.json file

What extensibility is provided here? Can you show me the code that you would write to get the extensibility that you need?

Yes, I've created a sample at https://github.com/bkoelman/OpenApiWithDocComments. The first commit is a standard Web API project, where I added OpenApiExtensions and documented the WeatherForecast type and members, and the controller action method. The second commit adds a class library that implements its own IOpenApiExampleMetadata (from OpenApiExtensions) to produce custom IOpenApiAny for examples. WeatherForecast doesn't contain logic to produce its example anymore, but the API project still needs to pass the example data via options. The third commit more accurately reflects the goal. Here, the class library defines ApiExampleValueAttribute, which the API project uses to express example data in WeatherForecast. The IOpenApiExampleMetadata implementation in the class library now reads the models from an EF Core DbContext, scans for usage of ApiExampleValueAttribute, and enriches that with extra information. Additionally, it enriches the documentation from the controller action method by plugging into OpenApiExtensionsOptions.DescriptionTransformations (from OpenApiExtensions) and enriching there as well.

From an extensibility perspective, this is still not as great as I hoped for, but at least it's heading in a usable direction. Because everything happens at runtime, third-party code can replace built-in services in the dependency container with custom implementations, which avoids executing the built-in logic. A third-party source generator can't prevent the built-in one from running and it must duplicate any built-in generation logic because it can't fallback to parts of the source generator.

If more information ended up in metadata, it would be easier to intercept. And then we wouldn't need to create IOpenApiAny instances, but instead leave that up to the library.

leveraging the existing building blocks in ASP.NET.

Yes, that's because it uses transformer and ApiExplorer metadata, which is the same approach that a source generator-based implementation would be based on. With that in mind...

Please drop the non-extensible source generator effort proposed here in favor of how the openapi-extensions library works.

You've not clarified how a source generator makes the implementation non-extensible by default or what kind of extensibility you care about. In this comment, you stated that you want to be able to access XML docs in the EndpointDescriptions. The package you referenced doesn't provide this extensibility either. It sets the XML information directly in the OpenAPI document using transformers, using the same extensibility strategy that the source generator-based approach uses.

I've provided examples of the extensibility we need at #39927 (comment). A source generator makes the implementation non-extensible because third-party code can't interact with it. It's an all-or-nothing experience. We could turn it off entirely, but then we'd also miss out on the generated code that translates metadata to OpenAPI. Similar to how we replace the built-in ASP.NET model validation today, we'd like to interact with (or replace, not undo afterward) the code that produces descriptions from triple-slash comments, but still rely on translating them from metadata to OpenAPI. This is why I'd like them to end up in the metadata.

I'm starting to understand why a source generator is most convenient to implement. A roslyn visitor is used to build the documentation, which needs a Compilation as input. However, the same logic could still be used at runtime, such as done in the command-line tool here.

What does matter to me is that source generators are being added more and more, which increases build time, severely degrading the inner loop experience in large projects.

This concern is completely separate from the discussion here. Code with poor performance characteristics is not exclusive to source generators and the assumption that just because something is implemented as a source generator it has inherently poor performance characteristics is invalid.

No, it is not. I'm not referring to code with poor performance characteristics, this is about how often it executes. The runtime provides source generators for JSON and regular expressions. While I haven't encountered projects containing thousands of regular expressions or JSON models, an API with thousands of endpoints and models isn't uncommon in enterprise-grade applications. Furthermore, the need for tweaking the logic that evaluates regular expressions is extremely rare, while JSON provides extensibility via converters (which enable to replace logic, not just supplement it).

The performance hit from using source generators is not a theoretical concern. I've experienced firsthand that introducing a source generator in a large project degraded the development experience so much that it made me buy a new desktop computer. While source generators can be incremental, each project/solution build runs everything. So every time I build this project, I'm confronted with the slowdown. This happens all the time, while working on code that is unrelated to the source-generated bits. I've contributed a lot to https://github.com/dotnet/roslyn-analyzers in the past (and even got a LinkedIn recommendation from one of the C# team members), so I'm pretty familiar with writing such code that executes on almost every keystroke.

Furthermore, we've had complaints from users that separate models from APIs in different projects, after we introduced a source generator that produces API-related code. It simply doesn't work. The source generator (which runs during build of the API project) scans for attributes on the models, but it won't see them in referenced projects. The only option in that case is to turn off the source generator entirely and revert back to handwritten code.

I've tried the steps from #39927 (comment), but it doesn't work with .NET 9. It shows a compile error that the source generator didn't run because of a FileNotFoundException for System.Text.Json v8.0.0.0. Adding an explicit package reference didn't solve that.

@bricelam
Copy link
Contributor

NSwag is really bad at preserving XML doc comment formatting. OpenAPI specifies support for markdown. Please consider the formatting of tags like c, code, list, para, and see while implementing this feature.

@captainsafia
Copy link
Member Author

captainsafia commented Feb 15, 2025

The PR to add support for this was merged into main yesterday so it should land in .NET 10 Preview 2. Some general notes:

  • It will work for both minimal and controller-based APIs.
  • It's part of the Microsoft.AspNetCore.OpenApi package.
  • It's on-by-default when you reference the Microsoft.AspNetCore.OpenApi package in your projects.
  • The implementation automatically discovers XML docs (if they exist) from the application assembly and any ProjectReferences. It doesn't automatically pick up XML docs from NuGet package references.
  • You can control what XML files are used by modifying the AdditionalFiles item group in MSBuild.
  • The implementation resolves inheritdoc tags using the same logic used in Roslyn workspaces (aka VS). Note: this is currently limited to types defined in the compilation assembly. See XML doc generation support should resovle inheritdoc in additional files #60466 for more info.
  • The implementation resolves list and para tags into the appropriate CommonMark entities.
  • The implementation resolves c, seealso and see into plain text. In the future, we might consider supporting being able to link to schemas defined in component/schemas if we can pick up the ref that matches but that might involve more work.

Nightly builds of the package are available (via these instructions) for anyone to try out.

mburumaxwell added a commit to tinglesoftware/dotnet-extensions that referenced this issue Feb 21, 2025
The extensions will be moved to a new package dependent on `Microsoft.AspNetCore.OpenApi` in a follow-up PR. The changes in Swashbuckle are becoming harder to keep up with. The new package has support for numerous scenarios, AoT, and inhertdoc XML comments as seen in dotnet/aspnetcore#39927 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-minimal-actions Controller-like actions for endpoint routing feature-openapi
Projects
No open projects
Status: No status
Development

No branches or pull requests