-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Update to Microsoft.OpenApi v2.0.0-preview.17 #61541
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
Conversation
captainsafia
commented
Apr 17, 2025
•
edited
Loading
edited
- React to nullable annotations changes in types
- React to OperationType -> HttpMethod move
- React to Annotations -> Metadata rename
- React to discriminator mapping using OpenApiSchemaReference
- React to Reader package being renamed to YamlReader
@@ -661,7 +677,7 @@ private async Task<OpenApiRequestBody> GetFormRequestBody( | |||
var contentType = requestFormat.MediaType; | |||
requestBody.Content[contentType] = new OpenApiMediaType | |||
{ | |||
Schema = schema | |||
Schema = complexTypeSchema ?? schema |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not following this change. Can you explain it? And does it need a new test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm working a bit around some of the new strictness in the APIs. The IOpenApiSchema
has two implementations OpenApiSchema
which represents a resolved schema and has set/get on all properties and OpenApiSchemaaReference
which is a pointer to a schema and only exposes a get on properties.
The schema
variable represents a resolved schema that we construct and populate with form parameters depending on some specific rules. For example, if you have multiple parameters annotated with [FromForm]
like in this test we generate a schema that uses allOf
to indicate that all of the properties in each type should appear in a single form payload.
When there is a single parameter annotated with [FromForm]
and it is a complex type then the binding implementation resolves from its properties directly. This test validates that behavior.
@@ -383,6 +387,29 @@ public Task TransformAsync(OpenApiOperation operation, OpenApiOperationTransform | |||
|
|||
return Task.CompletedTask; | |||
} | |||
|
|||
private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceParameter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this - I might borrow it for Swashbuckle 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm -- I wonder if it might be worth integrating into the Microsoft.OpenAPI APIs? Let me know how it shakes out for you in practice and we can consider moving it to the base library?
"PATCH" => HttpMethod.Patch, | ||
"HEAD" => HttpMethod.Head, | ||
"OPTIONS" => HttpMethod.Options, | ||
"TRACE" => HttpMethod.Trace, | ||
_ => throw new InvalidOperationException($"Unsupported HTTP method: {apiDescription.HttpMethod}"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC there's a bug logged somewhere about an exception being throw for the empty string in MVC instead of being a GET. If you're touching this area maybe fix that here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the right fix for that bug is to fix the ApiExplorer layer so that GET
is the assumed default for MVC controller actions that don't explicitly set it. That way we can retain the behavior of throwing for actually invalid HTTP methods here.
HttpMethod.Options, | ||
HttpMethod.Head, | ||
HttpMethod.Patch, | ||
HttpMethod.Trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen an issue that there's a new QUERY method coming soon, so that might need adding shortly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, the OpenAPI spec doesn't yet support all HTTP methods. There's been discussion of loosening this requirement in the past but at the moment it only supports this fixed set.
...pNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ResponseSchemas.cs
Show resolved
Hide resolved
@@ -31,17 +31,25 @@ public void MapRelativePathToItemPath_ReturnsItemPathForApiDescription(string re | |||
Assert.Equal(expectedItemPath, itemPath); | |||
} | |||
|
|||
public static class HttpMethodTestData | |||
{ | |||
public static IEnumerable<object[]> TestCases => new List<object[]> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding my comment about QUERY, is it worth adding a reflection-based test that checks for HttpMethod
having any new static property to flush out the need to react to any addition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can probably forgo on this until the spec supports more HTTP methods. From my understanding, moving from OperationType to HttpMethod in this breaking change was a setup for that.
@@ -407,7 +407,7 @@ private static OpenApiParameter UnwrapOpenApiParameter(IOpenApiParameter sourceP | |||
} | |||
else | |||
{ | |||
throw new InvalidOperationException("The input schema must be an OpenApiParameter or OpenApiParameterReference."); | |||
throw new InvalidOperationException("The input schema must be an {nameof(OpenApiParameter)} or {nameof(OpenApiParameterReference)}."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw new InvalidOperationException("The input schema must be an {nameof(OpenApiParameter)} or {nameof(OpenApiParameterReference)}."); | |
throw new InvalidOperationException($"The input schema must be an {nameof(OpenApiParameter)} or {nameof(OpenApiParameterReference)}."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
omg I hate myself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one did make me feel bad 😅 when I spotted it in the snapshots
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's ok I groaned harder on the other whitespace issue
I really wish there was a nicer templating story for source generated files so you could catch these kinds of things more easily
@@ -338,6 +338,8 @@ await VerifyOpenApiDocument(action, document => | |||
[([MinLength(2)] int[] id) => {}, (OpenApiSchema schema) => Assert.Equal(2, schema.MinItems)], | |||
[([Length(4, 8)] int[] id) => {}, (OpenApiSchema schema) => { Assert.Equal(4, schema.MinItems); Assert.Equal(8, schema.MaxItems); }], | |||
[([Range(4, 8)]int id) => {}, (OpenApiSchema schema) => { Assert.Equal("4", schema.Minimum); Assert.Equal("8", schema.Maximum); }], | |||
[([Range(1234, 5678)]int id) => {}, (OpenApiSchema schema) => { Assert.Equal("1234", schema.Minimum); Assert.Equal("5678", schema.Maximum); }], | |||
[([Range(1234.56, 7891.1)] decimal id) => {}, (OpenApiSchema schema) => { Assert.Equal("1234.56", schema.Minimum); Assert.Equal("7891.1", schema.Maximum); }], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[([Range(1234.56, 7891.1)] decimal id) => {}, (OpenApiSchema schema) => { Assert.Equal("1234.56", schema.Minimum); Assert.Equal("7891.1", schema.Maximum); }], | |
[([Range(1234.56, 7891.1)] decimal id) => {}, (OpenApiSchema schema) => { Assert.Equal("1234.56", schema.Minimum); Assert.Equal("7891.1", schema.Maximum); }], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:groan:
I'm guessing this missed the ⛵ for preview 4? |
Oh, yeah, it's too late unless we really need it. I should have merged it for her since she's out... |
It would be nice as there's a big dependency chain for stuff like Swashbuckle.AspNetCore where we can't use newer previews of Microsoft.OpenApi due to various binary-breaking changes along the way since p11, so without it we can't test anything newer until June (domaindrivendev/Swashbuckle.AspNetCore#3283 (comment)) |
/backport to release/10.0-preview4 |
Started backporting to release/10.0-preview4: https://github.com/dotnet/aspnetcore/actions/runs/14649645511 |