Add support for resource inheritance in OpenAPI#1704
Merged
Conversation
Renames in OAS output: - [ResourceName] Primary Response Document -> Primary [ResourceName] Response Document - [ResourceName] Secondary Response Document -> Secondary [ResourceName] Response Document - Nullable [ResourceName] Secondary Response Document -> Nullable Secondary [ResourceName] Response Document - Data In Response -> Resource In Response - [ResourceName] Data In Response -> Data In [ResourceName] Response - [ResourceName] Attributes In Response -> Attributes In [ResourceName] Response - [ResourceName] Relationships In Response -> Relationships In [ResourceName] Response
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## openapi #1704 +/- ##
===========================================
+ Coverage 90.34% 90.41% +0.07%
===========================================
Files 462 466 +4
Lines 14080 14434 +354
Branches 2198 2283 +85
===========================================
+ Hits 12720 13050 +330
- Misses 921 933 +12
- Partials 439 451 +12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
3b2eb6b to
c9bb868
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds full OpenAPI support for resource inheritance in JSON:API.
Foundational changes
Component schema renames
To generate a universal set of schema/type names for JSON:API with and without resource inheritance, this PR applies the following renames. They affect the OpenAPI file and the type names of the generated code.
Hopefully, this is the final set of renames. It affects everyone who uses the pre-release versions; sorry for that.
Structural changes
The component schemas for the following request types now always have a shared abstract base type:
The resource type for resource data is now defined in a shared enumeration that lists all resource types, so there are no more resource-specific single-valued enumerations. This hasn't changed for resource identifiers.
Either way, these enumerations matter only to kiota users, who must specify the resource type explicitly. NSwag handles discriminator properties automatically and doesn't even expose them.
Resource inheritance
In short, there's a fundamental mismatch between the concept of inheritance in object-oriented design and composition in OpenAPI. NSwag overcomes that by breaking the inheritance chain in C#, while Kiota doesn't support it at all. See microsoft/kiota#5086 for the details.
To make it work in both tools, this PR introduces a JSON:API extension that allows sending an extra discriminator (which JsonApiDotNetCore ignores) in attributes, relationships and operations. This JSON:API OpenAPI extension is documented in
/docs/ext/openapi/index.md. The extension is automatically activated when using theJsonApiDotNetCore.OpenApi.Swashbucklepackage. The package hooks into the JsonApiDotNetCore content negotiation and serializer to validate the extra discriminators on incoming JSON:API requests.Because of the above mismatch, clients must upcast attributes and relationships to access derived properties.
For example:
Unfortunately, this is unavoidable.
Implementation details
This PR improves the detection of unused component schemas in the output file. When tests run in DEBUG mode, they fail when unused component schemas appear in the OpenAPI output. It still does not detect types that only appear in discriminator mappings without being referenced elsewhere.
ResourceIdentifierSchemaGeneratorandAbstractResourceDataSchemaGeneratorgot merged intoDataSchemaGenerator.AbstractAtomicOperationSchemaGeneratorgot merged intoAtomicOperationsBodySchemaGenerator, which was renamed toAtomicOperationsDocumentSchemaGenerator.DataSchemaGenerator,DataContainerSchemaGeneratorandAtomicOperationsDocumentSchemaGeneratorwere heavily refactored to support inheritance.SetSchemaTypeToObjectDocumentFilterwas added to workaround a bug in NSwag where it's unable to infer the proper schema type, resulting in invalid generated code.To workaround kiota bug microsoft/kiota#2432, the applicable discriminator mappings are repeated in every derived type in a type hierarchy (applies to types used in responses only).
An extensive suite of tests was added for several combinations with resource inheritance:
Closes #1457.
QUALITY CHECKLIST