Add aspnet-openapi skill (#dotnet-aspnet)#486
Conversation
|
@dotnet-policy-service agree |
There was a problem hiding this comment.
Pull request overview
Adds a new aspnet-openapi skill to the dotnet-aspnet plugin to guide ASP.NET Core OpenAPI setup and migration (built-in Microsoft.AspNetCore.OpenApi vs Swashbuckle/NSwag), with supporting reference docs and eval scenarios.
Changes:
- Added
aspnet-openapiskill documentation with end-to-end setup guidance (Scalar/Swagger UI), endpoint annotation patterns, JWT security scheme via transformers, and production-hardening guidance. - Added reference docs covering transformer/filter equivalents and a Swashbuckle→built-in migration walkthrough.
- Added an eval suite with 4 scenarios to validate common OpenAPI setup/migration behaviors and pitfalls.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/dotnet-aspnet/aspnet-openapi/eval.yaml | Adds eval scenarios for built-in OpenAPI + Scalar, Swashbuckle empty-spec pitfall, JWT scheme transformer, and migration flow. |
| plugins/dotnet-aspnet/skills/aspnet-openapi/SKILL.md | New primary skill workflow doc for OpenAPI technology selection, setup, UI integration, transformers, and securing spec endpoints. |
| plugins/dotnet-aspnet/skills/aspnet-openapi/references/transformers.md | Reference patterns for document/operation/schema transformers and Swashbuckle filter equivalents. |
| plugins/dotnet-aspnet/skills/aspnet-openapi/references/swashbuckle-migration.md | Step-by-step migration guide including mapping table and post-migration troubleshooting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
6e44be4 to
a802f80
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fully-qualify System.Reflection.Assembly in Swashbuckle XML docs snippet (Assembly.GetExecutingAssembly is not in default global usings) - Add 'using Microsoft.OpenApi.Models' to the transformer registration snippet in references/transformers.md (OpenApiContact/OpenApiInfo are not in default global usings)
b6cf426 to
b4520f2
Compare
|
@copilot review this PR |
|
Tagging @danroth27 for thoughts on this. Please feel free to loop in anyone else on the team who might be able to help as well. |
|
Adding @mikekistler @Youssef1313 and @javiercn to take a look. |
mikekistler
left a comment
There was a problem hiding this comment.
Thanks for this submission!
I left comments on a number of small issues that need to be addressed.
| - You need features the built-in package does not yet support (advanced polymorphism, | ||
| `oneOf`/`anyOf` discriminators, complex `$ref` scenarios) |
There was a problem hiding this comment.
Not sure what this is referring to. Built-in OpenAPI generation supports polymorphism, oneOf and anyOf schemas, and most complex $ref scenarios I'm aware of. I think more specific guidance is needed here.
|
|
||
| ## Migrate or Stay? | ||
|
|
||
| Migration is not mandatory. Swashbuckle continues to work on .NET 9+ with version 7.x. |
There was a problem hiding this comment.
The current latest version of Swashbuckle.AspNetCore is 10.1.7, and has many improvements over v7.x. Is this recommending against using packages more recent than 7.x? Maybe this should say "7.x or later"?
| <PackageReference Include="Swashbuckle.AspNetCore" Version="7.*" /> | ||
|
|
||
| <!-- Add --> | ||
| <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.*" /> |
There was a problem hiding this comment.
Is this skill .NET 9 specific? How do we write this in a way that makes it applicable to .NET 9 and later?
| <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.*" /> | ||
|
|
||
| <!-- If you still want Swagger UI instead of Scalar --> | ||
| <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="7.*" /> |
There was a problem hiding this comment.
Here too, I think we should recommend the most recent version of washbuckle.AspNetCore.SwaggerUI.
Maybe we should be recommending a dotnet add package command, rather than specific updates to the csproj, so that the right levels are used automatically.
| | `context.ApiDescription` (in `IOperationFilter`) | `context.Description` | Same type: `ApiDescription` | | ||
|
|
||
| ### XML Documentation Note | ||
|
|
There was a problem hiding this comment.
I think metadata from XML doc comments was not added to ASP.NET Core until .NET 10. I think that should be mentioned here.
| For **minimal APIs**, XML comments on the handler delegate are not picked up | ||
| automatically — use `.WithSummary()` and `.WithDescription()` on the endpoint | ||
| instead (shown in SKILL.md Step 5). For **MVC controller actions**, XML `<summary>` |
There was a problem hiding this comment.
Recommend defining the delegate as a local method, as described above.
| By default, enums serialize as integers in the spec. To represent them as string values: | ||
|
|
||
| ```csharp | ||
| using Microsoft.AspNetCore.OpenApi; | ||
| using Microsoft.OpenApi.Any; | ||
| using Microsoft.OpenApi.Models; | ||
|
|
||
| internal sealed class EnumSchemaTransformer : IOpenApiSchemaTransformer | ||
| { | ||
| public Task TransformAsync( | ||
| OpenApiSchema schema, | ||
| OpenApiSchemaTransformerContext context, | ||
| CancellationToken cancellationToken) | ||
| { | ||
| if (context.JsonTypeInfo.Type.IsEnum) | ||
| { | ||
| schema.Type = "string"; | ||
| schema.Enum = Enum.GetNames(context.JsonTypeInfo.Type) | ||
| .Select(name => new OpenApiString(name)) | ||
| .Cast<IOpenApiAny>() | ||
| .ToList(); | ||
| } | ||
|
|
||
| return Task.CompletedTask; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| > This transformer only affects the OpenAPI schema. Ensure your `JsonSerializerOptions` | ||
| > (or `System.Text.Json` attributes) are also configured to serialize enums as strings at | ||
| > runtime — the spec and the actual wire format must agree. |
There was a problem hiding this comment.
Replace this whole section with "use JsonStringEnumConverter.
|
|
||
| ## Stop Signals | ||
|
|
||
| - **Need to generate C# or TypeScript API clients?** — Use NSwag or `dotnet-openapi`. This skill covers spec *generation*, not *consumption*. |
There was a problem hiding this comment.
There are plenty of options for generating clients besides NSwag, for example Kiota, that take OpenAPI as input, so I don't think this is necessarily a "stop signal".
| | Need typed client code generation | `NSwag.AspNetCore` | Only mature option with C#/TypeScript codegen; pair with the spec output | | ||
| | Complex polymorphism or discriminators | `NSwag.AspNetCore` | More schema control than either alternative | |
There was a problem hiding this comment.
Neither of these cases should recommend against using built-in OpenAPI doc generation.
| The spec is only as useful as the metadata you put in. Sparse annotations produce a sparse, | ||
| useless spec — and waste the entire investment in Step 2–4. | ||
|
|
||
| **Minimal APIs:** |
There was a problem hiding this comment.
This section should show an example with XML doc comments as the source of OpenAPI metadata.
Summary
Adds a new
aspnet-openapiskill to thedotnet-aspnetplugin covering OpenAPI documentation for ASP.NET Core APIs. This is a high-frequency, high-confusion area, .NET 9 replaced Swashbuckle as the default in project templates, leaving developers with contradictory guidance across tutorials, and the technology-selection and migration decisions are non-obvious without prior experience.What's included
SKILL.md— Full workflow covering:Microsoft.AspNetCore.OpenApi(.NET 9+) vs Swashbuckle vs NSwag, with a clear decision tableAddEndpointsApiExplorer()omission)Produces<T>,ProducesProblem,ExcludeFromDescription)IOpenApiDocumentTransformerreferences/transformers.md— Document, operation, and schema transformer patterns; OAuth2 and API key schemes; SwashbuckleIDocumentFilter/IOperationFilterequivalentsreferences/swashbuckle-migration.md— Step-by-step migration guide from Swashbuckle including filter→transformer mapping, behavioral differences table, and common post-migration failurestests/dotnet-aspnet/aspnet-openapi/eval.yaml— 4 eval scenarios covering basic setup, the Swashbuckle empty-spec gotcha, JWT security scheme configuration, and full Swashbuckle migrationMotivation
dotnet-aspnetcurrently has a single skill (minimal-api-file-upload). OpenAPI is arguably the most universally needed capability for any HTTP API, every team configures it, and the .NET 9 ecosystem shift means existing documentation and tutorials are inconsistent. This is a clear LLM gap: agents routinely suggest the wrong package for the target framework, omitAddEndpointsApiExplorer(), or produce security scheme configuration that doesn't match the built-in package's transformer API.