-
Notifications
You must be signed in to change notification settings - Fork 10k
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
OpenApi incorrect inline schema for multi-level objects #57799
Comments
@dnv-kimbell Thanks for reporting this issue! I believe this bug is caused by the level of recursion that we apply when mapping schemas by references in this bit of code. This particularly happens if you reference a type in a deeply nested structure and it is only referenced once in the entire document. Let me know if the hierarchy that you're dealing with matches these properties and I can look at expanding our test suite with this and adding a fix. |
This is not recursion, the class names just happen to be named similarly. If I add extra types with very different names, they are still inlined. To me it looks like it has problems handling deep object structures; first level using reference is ok, rest is inlined.
|
I did some more testing. I added a new operation that returns an object. This object is also returned as part of the response of my first operation. This object is added under schemas, but not referenced using ref in the other response. Repro has been updated. I'm struggling to see how this is supposed to work. One of the main use-cases for OpenApi is to generate code. In order to do that, we need the name of types being used; it must be possible to do Added an enum, and that is added to the schemas section and referenced where it's being used. This is what I would have expected for all object types. I added another operation that returns an IEnumerable of a type returned as part of the response of other operations. I shows that it returns 200, but doesn't contain any information about the type; not inlined or by reference. None of the operations show any schema data for responses.
|
The recursion I was referring to was in the code that applies the updates to $ref in the child properties. Currently, it only recurses into the first level of schema references in an object. I wasn't referring to recursive types themselves. OK, so some details about how things work under the hood for those who are curious. There are two components at play when we generate schemas for OpenAPI documents:
Because of this two step process, there's not a discernible location for us to convert inline schemas to ref-based schemas as we are discovering types. Let's take a look at the
The biggest difference between Swashbuckle's schema implementation and M.A.OpenApi's is the fact that we take a dependency on System.Text.Json's APIs for schema generation, where as Swashbuckle has its own bespoke schema generation implementation. There's benefits to using the STJ APIs:
It does come with one noticeable downside: Swashbuckle can construct OpenApiSchemas directly as it walks the type hierarchy and can manage the mapping of inline schemas to refs as it construct it, we have to mediate between the APIs provided by STJ, the We could try to apply the schema reference caching in the I hope that clarifies the confusion as to the current behavior and why we map references after schemas have been generated instead of during the schema generation process. The long and short of it being that we don't have any good APIs to do it during the moment. There have been conversations about moving the TL;DR: We need to fix the code referenced above to examine more deeply nested structures. Let me know if you have any follow-up questions on this bit. I'll respond to the issue you're seeing with response schemas in a different comment... |
I believe issue here is the top-level aspnetcore/src/OpenApi/src/Services/OpenApiDocumentService.cs Lines 377 to 386 in bb3b2e9
We'll want to I'll see if we can get a bug fixes in for these before .NET 9 GA... |
I always appreciate more detailed information. With the current implementation, I'm struggling to see how this will work in the real world. Applications will be sending deep object structures. In order to create these, languages such as C# will require things to be represented as set of classes. Since anything below level 1 is inlined, any code generator needs to come up with names for these inline types. If the same type is referenced multiple times in different responses on the server, you risk ending up with two different objects on the client that should be the same. Some application out there will be returning an address as part of a GET response, and taking the same address in a POST request. It would be nice if the client also could use the same type for both operations. |
@dnv-kimbell Both of the bugs that you reported are now resolved in the latest .NET 9 RC 2 builds of the package. Can you try them out and see how things are looking for you? To access the nightly builds, add the following package reference to your
And use the following
|
These cases seem to be resolved. In order to get it to work, I had to use Now that I have moved passed this issue, I have found other things that don't work as expected. Will file different issues for those cases. |
Great! I'll close this out and we can track the other issues separately. |
Is there an existing issue for this?
Describe the bug
We are looking into replacing Swashbuckle with the new OpenApi functionality. We have created a sample application to see what is different in the generated schema. I discovered one difference I can't explain.
We have a controller that uses this object structure
In the generated json, the EchoData3 is inlined into EchoData2. This doesn't seem right.
Expected Behavior
I would expect a schema entry for every class being used. When using code generation tools, naming this inline object becomes tricky.
Steps To Reproduce
Check out code at: https://github.com/dnv-kimbell/openapi-inlineschema
Exceptions (if any)
No response
.NET Version
9.0 RC1
Anything else?
No response
The text was updated successfully, but these errors were encountered: