diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index b1fef4561c..7ffe7047ca 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
   "isRoot": true,
   "tools": {
     "jetbrains.resharper.globaltools": {
-      "version": "2025.2.3",
+      "version": "2025.3.0-eap07",
       "commands": [
         "jb"
       ],
@@ -24,7 +24,7 @@
       "rollForward": false
     },
     "docfx": {
-      "version": "2.78.2",
+      "version": "2.78.4",
       "commands": [
         "docfx"
       ],
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 35313888ef..d706bf868c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -12,7 +12,7 @@ on:
   workflow_dispatch:
   pull_request:
   push:
-    branches: [ 'master', 'release/**' ]
+    branches: [ 'master', 'release/**', 'net10-preview' ]
   release:
     types: [published]
 
@@ -48,6 +48,11 @@ jobs:
         dotnet-version: |
           8.0.*
           9.0.*
+    - name: Setup .NET 10 preview
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: 10.0.*
+        dotnet-quality: 'preview'
     - name: Show installed versions
       shell: pwsh
       run: |
@@ -159,6 +164,11 @@ jobs:
         dotnet-version: |
           8.0.*
           9.0.*
+    - name: Setup .NET 10 preview
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: 10.0.*
+        dotnet-quality: 'preview'
     - name: Git checkout
       uses: actions/checkout@v5
     - name: Restore tools
@@ -168,6 +178,7 @@ jobs:
       run: |
         $inspectCodeOutputPath = Join-Path $env:RUNNER_TEMP 'jetbrains-inspectcode-results.xml'
         Write-Output "INSPECT_CODE_OUTPUT_PATH=$inspectCodeOutputPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
+        dotnet jb inspectcode --version
         dotnet jb inspectcode JsonApiDotNetCore.sln --build --dotnetcoresdk=$(dotnet --version) --output="$inspectCodeOutputPath" --format="xml" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:ContinuousIntegrationBuild=false --properties:RunAnalyzers=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal
     - name: Upload output to artifacts
       uses: actions/upload-artifact@v4
@@ -218,6 +229,11 @@ jobs:
         dotnet-version: |
           8.0.*
           9.0.*
+    - name: Setup .NET 10 preview
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: 10.0.*
+        dotnet-quality: 'preview'
     - name: Git checkout
       uses: actions/checkout@v5
       with:
@@ -236,12 +252,14 @@ jobs:
         $baseCommitHash = git rev-parse HEAD~1
 
         Write-Output "Running code cleanup on commit range $baseCommitHash..$headCommitHash in pull request."
+        dotnet jb cleanupcode --version
         dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --properties:RunAnalyzers=false --jb --verbosity=WARN -f commits -a $headCommitHash -b $baseCommitHash --fail-on-diff --print-diff
     - name: CleanupCode (on branch)
       if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }}
       shell: pwsh
       run: |
         Write-Output 'Running code cleanup on all files.'
+        dotnet jb cleanupcode --version
         dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --properties:RunAnalyzers=false --jb --verbosity=WARN --fail-on-diff --print-diff
 
   publish:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 0ff1bb17be..30df90d0dc 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -28,6 +28,11 @@ jobs:
         dotnet-version: |
           8.0.*
           9.0.*
+    - name: Setup .NET 10 preview
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: 10.0.*
+        dotnet-quality: 'preview'
     - name: Git checkout
       uses: actions/checkout@v5
     - name: Initialize CodeQL
diff --git a/Directory.Build.props b/Directory.Build.props
index e5323c6c76..ddf431d59a 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -15,6 +15,12 @@
     direct
   
 
+  
+    
+    true
+    $(NoWarn);CA1873;NU1903;NU5104;NU1608;IDE0340
+  
+
   
     
+    10.0.*-*
+    10.0.0-pr.3283.*
+
+    
+    10.0.*-*
+    10.0.0-pr.3283.*
+    2.3.*
+    10.0.*-*
+    10.0.*-*
+    9.0.*
+  
+
   
     
     N/A
@@ -42,6 +56,7 @@
     
     9.0.*
     9.0.*
+    9.0.*
   
 
   
@@ -51,5 +66,6 @@
     
     8.0.*
     8.0.*
+    8.0.*
   
 
diff --git a/src/Examples/DapperExample/DapperExample.csproj b/src/Examples/DapperExample/DapperExample.csproj
index 0685dc0343..b2c71ee0f8 100644
--- a/src/Examples/DapperExample/DapperExample.csproj
+++ b/src/Examples/DapperExample/DapperExample.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0;net8.0
+    net10.0;net9.0;net8.0
   
 
   
@@ -14,8 +14,9 @@
   
     
     
+    
     
     
-    
+    
   
 
diff --git a/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj b/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj
index 3edc993428..c7cee804b1 100644
--- a/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj
+++ b/src/Examples/DatabasePerTenantExample/DatabasePerTenantExample.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0;net8.0
+    net10.0;net9.0;net8.0
   
 
   
diff --git a/src/Examples/GettingStarted/GettingStarted.csproj b/src/Examples/GettingStarted/GettingStarted.csproj
index 611aeb37a5..806fdf45a5 100644
--- a/src/Examples/GettingStarted/GettingStarted.csproj
+++ b/src/Examples/GettingStarted/GettingStarted.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0;net8.0
+    net10.0;net9.0;net8.0
   
 
   
diff --git a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
index 768a2de827..319c72b262 100644
--- a/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
+++ b/src/Examples/JsonApiDotNetCoreExample/JsonApiDotNetCoreExample.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0;net8.0
+    net10.0
     true
     GeneratedSwagger
   
diff --git a/src/Examples/JsonApiDotNetCoreExample/SetOpenApiServerAtBuildTimeFilter.cs b/src/Examples/JsonApiDotNetCoreExample/SetOpenApiServerAtBuildTimeFilter.cs
index 894c0d0966..adf32ffde7 100644
--- a/src/Examples/JsonApiDotNetCoreExample/SetOpenApiServerAtBuildTimeFilter.cs
+++ b/src/Examples/JsonApiDotNetCoreExample/SetOpenApiServerAtBuildTimeFilter.cs
@@ -1,5 +1,5 @@
 using JetBrains.Annotations;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCoreExample;
@@ -16,6 +16,8 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
     {
         if (_httpContextAccessor.HttpContext == null)
         {
+            swaggerDoc.Servers ??= [];
+
             swaggerDoc.Servers.Add(new OpenApiServer
             {
                 Url = "https://localhost:44340"
diff --git a/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj b/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj
index 611aeb37a5..806fdf45a5 100644
--- a/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj
+++ b/src/Examples/MultiDbContextExample/MultiDbContextExample.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0;net8.0
+    net10.0;net9.0;net8.0
   
 
   
diff --git a/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj b/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj
index 15a485c08f..e50874f733 100644
--- a/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj
+++ b/src/Examples/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0;net8.0
+    net10.0;net9.0;net8.0
   
 
   
diff --git a/src/Examples/OpenApiKiotaClientExample/OpenApiKiotaClientExample.csproj b/src/Examples/OpenApiKiotaClientExample/OpenApiKiotaClientExample.csproj
index 8f65b2b688..8dd3e2e4df 100644
--- a/src/Examples/OpenApiKiotaClientExample/OpenApiKiotaClientExample.csproj
+++ b/src/Examples/OpenApiKiotaClientExample/OpenApiKiotaClientExample.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0
+    net10.0
   
 
   
diff --git a/src/Examples/OpenApiNSwagClientExample/OpenApiNSwagClientExample.csproj b/src/Examples/OpenApiNSwagClientExample/OpenApiNSwagClientExample.csproj
index c30833a39a..079e43121c 100644
--- a/src/Examples/OpenApiNSwagClientExample/OpenApiNSwagClientExample.csproj
+++ b/src/Examples/OpenApiNSwagClientExample/OpenApiNSwagClientExample.csproj
@@ -1,7 +1,7 @@
 
   
     
-    net9.0
+    net10.0
   
 
   
diff --git a/src/Examples/ReportsExample/ReportsExample.csproj b/src/Examples/ReportsExample/ReportsExample.csproj
index 6ade1386be..73a16ddf4f 100644
--- a/src/Examples/ReportsExample/ReportsExample.csproj
+++ b/src/Examples/ReportsExample/ReportsExample.csproj
@@ -1,6 +1,6 @@
 
   
-    net9.0;net8.0
+    net10.0;net9.0;net8.0
   
 
   
diff --git a/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj b/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj
index d615476081..fd646bfd78 100644
--- a/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj
+++ b/src/JsonApiDotNetCore.Annotations/JsonApiDotNetCore.Annotations.csproj
@@ -1,6 +1,6 @@
 
   
-    net8.0;netstandard1.0
+    net10.0;net8.0;netstandard1.0
     true
     true
     JsonApiDotNetCore
diff --git a/src/JsonApiDotNetCore.OpenApi.Client.Kiota/JsonApiDotNetCore.OpenApi.Client.Kiota.csproj b/src/JsonApiDotNetCore.OpenApi.Client.Kiota/JsonApiDotNetCore.OpenApi.Client.Kiota.csproj
index 640b949477..fce1fb7c40 100644
--- a/src/JsonApiDotNetCore.OpenApi.Client.Kiota/JsonApiDotNetCore.OpenApi.Client.Kiota.csproj
+++ b/src/JsonApiDotNetCore.OpenApi.Client.Kiota/JsonApiDotNetCore.OpenApi.Client.Kiota.csproj
@@ -1,6 +1,6 @@
 
   
-    net8.0
+    net10.0;net8.0
     true
     true
     false
diff --git a/src/JsonApiDotNetCore.OpenApi.Client.NSwag/JsonApiDotNetCore.OpenApi.Client.NSwag.csproj b/src/JsonApiDotNetCore.OpenApi.Client.NSwag/JsonApiDotNetCore.OpenApi.Client.NSwag.csproj
index 20e2306730..550f284509 100644
--- a/src/JsonApiDotNetCore.OpenApi.Client.NSwag/JsonApiDotNetCore.OpenApi.Client.NSwag.csproj
+++ b/src/JsonApiDotNetCore.OpenApi.Client.NSwag/JsonApiDotNetCore.OpenApi.Client.NSwag.csproj
@@ -1,6 +1,6 @@
 
   
-    net8.0
+    net10.0;net8.0
     true
     true
     false
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/ConfigureSwaggerGenOptions.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/ConfigureSwaggerGenOptions.cs
index ec21712688..f8a6deffaa 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/ConfigureSwaggerGenOptions.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/ConfigureSwaggerGenOptions.cs
@@ -76,6 +76,7 @@ public void Configure(SwaggerGenOptions options)
         options.DocumentFilter();
         options.DocumentFilter();
         options.DocumentFilter();
+        options.DocumentFilter();
     }
 
     private List SelectDerivedTypes(Type baseType)
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiDotNetCore.OpenApi.Swashbuckle.csproj b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiDotNetCore.OpenApi.Swashbuckle.csproj
index 4a57ca1c85..b8be841a34 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiDotNetCore.OpenApi.Swashbuckle.csproj
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiDotNetCore.OpenApi.Swashbuckle.csproj
@@ -1,6 +1,6 @@
 
   
-    net8.0
+    net10.0
     true
     true
     false
@@ -33,6 +33,7 @@
   
 
   
+    
     
     
   
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiSchemaIdSelector.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiSchemaIdSelector.cs
index d31c324713..3008a9a787 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiSchemaIdSelector.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiSchemaIdSelector.cs
@@ -115,7 +115,7 @@ public string GetSchemaId(Type type)
 
     private string ApplySchemaTemplate(string schemaTemplate, ResourceType? resourceType, string? relationshipName, AtomicOperationCode? operationCode)
     {
-        string schemaId = schemaTemplate;
+        string? schemaId = schemaTemplate;
 
         schemaId = resourceType != null
             ? schemaId.Replace("[ResourceName]", resourceType.PublicName.Singularize()).Pascalize()
@@ -131,7 +131,7 @@ private string ApplySchemaTemplate(string schemaTemplate, ResourceType? resource
             schemaId = schemaId.Replace("[OperationCode]", operationCode.Value.ToString().Pascalize());
         }
 
-        string pascalCaseSchemaId = schemaId.Pascalize();
+        string? pascalCaseSchemaId = schemaId.Pascalize();
 
         JsonNamingPolicy? namingPolicy = _options.SerializerOptions.PropertyNamingPolicy;
         return namingPolicy != null ? namingPolicy.ConvertName(pascalCaseSchemaId) : pascalCaseSchemaId;
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/MicrosoftOpenApiCompatibilityExtensions.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/MicrosoftOpenApiCompatibilityExtensions.cs
new file mode 100644
index 0000000000..9fce2ccfd5
--- /dev/null
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/MicrosoftOpenApiCompatibilityExtensions.cs
@@ -0,0 +1,24 @@
+using Microsoft.OpenApi;
+
+namespace JsonApiDotNetCore.OpenApi.Swashbuckle;
+
+internal static class MicrosoftOpenApiCompatibilityExtensions
+{
+    public static void SetNullable(this OpenApiSchema schema, bool nullable)
+    {
+        ArgumentNullException.ThrowIfNull(schema);
+
+        if (nullable)
+        {
+            schema.Type ??= JsonSchemaType.Null;
+            schema.Type |= JsonSchemaType.Null;
+        }
+        else
+        {
+            if (schema.Type != null)
+            {
+                schema.Type &= ~JsonSchemaType.Null;
+            }
+        }
+    }
+}
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiDescriptionLinkProvider.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiDescriptionLinkProvider.cs
index 278c2154a9..2638711d1c 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiDescriptionLinkProvider.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiDescriptionLinkProvider.cs
@@ -30,7 +30,7 @@ public OpenApiDescriptionLinkProvider(IOptionsMonitor s
 
         if (swaggerGeneratorOptions.SwaggerDocs.Count > 0)
         {
-            string latestVersionDocumentName = swaggerGeneratorOptions.SwaggerDocs.Last().Key;
+            string? latestVersionDocumentName = swaggerGeneratorOptions.SwaggerDocs.Last().Key;
 
             SwaggerOptions swaggerOptions = _swaggerOptionsMonitor.CurrentValue;
             return swaggerOptions.RouteTemplate.Replace("{documentName}", latestVersionDocumentName).Replace("{extension:regex(^(json|ya?ml)$)}", "json");
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiOperationIdSelector.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiOperationIdSelector.cs
index 065e26941c..2185657852 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiOperationIdSelector.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiOperationIdSelector.cs
@@ -105,7 +105,7 @@ private string ApplyTemplate(string openApiOperationIdTemplate, ResourceType? re
         // @formatter:wrap_chained_method_calls chop_always
         // @formatter:wrap_before_first_method_call true
 
-        string pascalCaseOpenApiOperationId = openApiOperationIdTemplate
+        string? pascalCaseOpenApiOperationId = openApiOperationIdTemplate
             .Replace("[Method]", method)
             .Replace("[PrimaryResourceName]", resourceType?.PublicName.Singularize())
             .Replace("[RelationshipName]", relationshipName)
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiSchemaExtensions.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiSchemaExtensions.cs
index 10095834b2..8e628be500 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiSchemaExtensions.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiSchemaExtensions.cs
@@ -1,4 +1,4 @@
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle;
 
@@ -9,22 +9,23 @@ public static void ReorderProperties(this OpenApiSchema fullSchema, IEnumerable<
         ArgumentNullException.ThrowIfNull(fullSchema);
         ArgumentNullException.ThrowIfNull(propertyNamesInOrder);
 
-        var propertiesInOrder = new Dictionary();
+        var propertiesInOrder = new Dictionary();
 
         foreach (string propertyName in propertyNamesInOrder)
         {
-            if (fullSchema.Properties.TryGetValue(propertyName, out OpenApiSchema? schema))
+            if (fullSchema.Properties != null && fullSchema.Properties.TryGetValue(propertyName, out IOpenApiSchema? schema))
             {
                 propertiesInOrder.Add(propertyName, schema);
             }
         }
 
+        ConsistencyGuard.ThrowIf(fullSchema.Properties == null);
         ConsistencyGuard.ThrowIf(fullSchema.Properties.Count != propertiesInOrder.Count);
 
         fullSchema.Properties = propertiesInOrder;
     }
 
-    public static OpenApiSchema WrapInExtendedSchema(this OpenApiSchema source)
+    public static OpenApiSchema WrapInExtendedSchema(this IOpenApiSchema source)
     {
         ArgumentNullException.ThrowIfNull(source);
 
@@ -34,11 +35,11 @@ public static OpenApiSchema WrapInExtendedSchema(this OpenApiSchema source)
         };
     }
 
-    public static OpenApiSchema UnwrapLastExtendedSchema(this OpenApiSchema source)
+    public static IOpenApiSchema UnwrapLastExtendedSchema(this IOpenApiSchema source)
     {
         ArgumentNullException.ThrowIfNull(source);
 
-        if (source.AllOf is { Count: > 0 })
+        if (source is OpenApiSchema && source.AllOf is { Count: > 0 })
         {
             return source.AllOf.Last();
         }
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/RemoveTagsFilter.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/RemoveTagsFilter.cs
new file mode 100644
index 0000000000..cbf7cc2839
--- /dev/null
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/RemoveTagsFilter.cs
@@ -0,0 +1,14 @@
+using JetBrains.Annotations;
+using Microsoft.OpenApi;
+using Swashbuckle.AspNetCore.SwaggerGen;
+
+namespace JsonApiDotNetCore.OpenApi.Swashbuckle;
+
+[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
+internal sealed class RemoveTagsFilter : IDocumentFilter
+{
+    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
+    {
+        swaggerDoc.Tags?.Clear();
+    }
+}
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/AtomicOperationCodeSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/AtomicOperationCodeSchemaGenerator.cs
index 78a25da441..053f15d708 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/AtomicOperationCodeSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/AtomicOperationCodeSchemaGenerator.cs
@@ -1,6 +1,5 @@
 using JsonApiDotNetCore.Serialization.Objects;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -19,7 +18,7 @@ public AtomicOperationCodeSchemaGenerator(SchemaGenerationTracer schemaGeneratio
         _schemaIdSelector = schemaIdSelector;
     }
 
-    public OpenApiSchema GenerateSchema(AtomicOperationCode operationCode, SchemaRepository schemaRepository)
+    public IOpenApiSchema GenerateSchema(AtomicOperationCode operationCode, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
@@ -27,14 +26,7 @@ public OpenApiSchema GenerateSchema(AtomicOperationCode operationCode, SchemaRep
 
         if (schemaRepository.Schemas.ContainsKey(schemaId))
         {
-            return new OpenApiSchema
-            {
-                Reference = new OpenApiReference
-                {
-                    Id = schemaId,
-                    Type = ReferenceType.Schema
-                }
-            };
+            return new OpenApiSchemaReference(schemaId);
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, operationCode);
@@ -43,11 +35,11 @@ public OpenApiSchema GenerateSchema(AtomicOperationCode operationCode, SchemaRep
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "string",
-            Enum = [new OpenApiString(enumValue)]
+            Type = JsonSchemaType.String,
+            Enum = [enumValue]
         };
 
-        OpenApiSchema referenceSchema = schemaRepository.AddDefinition(schemaId, fullSchema);
+        OpenApiSchemaReference? referenceSchema = schemaRepository.AddDefinition(schemaId, fullSchema);
 
         traceScope.TraceSucceeded(schemaId);
         return referenceSchema;
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataContainerSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataContainerSchemaGenerator.cs
index c4b41dd0f5..cfac742cee 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataContainerSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataContainerSchemaGenerator.cs
@@ -2,7 +2,7 @@
 using JsonApiDotNetCore.Configuration;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.ResourceObjects;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SwaggerComponents;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -27,21 +27,21 @@ public DataContainerSchemaGenerator(SchemaGenerationTracer schemaGenerationTrace
         _resourceGraph = resourceGraph;
     }
 
-    public OpenApiSchema GenerateSchemaForCommonResourceDataInResponse(SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchemaForCommonResourceDataInResponse(SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
         return _dataSchemaGenerator.GenerateSchemaForCommonData(typeof(ResourceInResponse), schemaRepository);
     }
 
-    public OpenApiSchema GenerateSchema(Type dataContainerSchemaType, ResourceType resourceType, bool forRequestSchema, bool canIncludeRelated,
+    public IOpenApiSchema GenerateSchema(Type dataContainerSchemaType, ResourceType resourceType, bool forRequestSchema, bool canIncludeRelated,
         SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(dataContainerSchemaType);
         ArgumentNullException.ThrowIfNull(resourceType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        if (schemaRepository.TryLookupByType(dataContainerSchemaType, out OpenApiSchema referenceSchemaForData))
+        if (schemaRepository.TryLookupByType(dataContainerSchemaType, out OpenApiSchemaReference? referenceSchemaForData))
         {
             return referenceSchemaForData;
         }
@@ -68,7 +68,7 @@ public OpenApiSchema GenerateSchema(Type dataContainerSchemaType, ResourceType r
         }
 
         referenceSchemaForData = _dataSchemaGenerator.GenerateSchema(dataConstructedType, forRequestSchema, schemaRepository);
-        traceScope.TraceSucceeded(referenceSchemaForData.Reference.Id);
+        traceScope.TraceSucceeded(referenceSchemaForData.Reference.Id!);
         return referenceSchemaForData;
     }
 
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataSchemaGenerator.cs
index 4d7783f780..28aa649af0 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataSchemaGenerator.cs
@@ -1,12 +1,13 @@
 using System.Collections.Concurrent;
 using System.Reflection;
 using System.Runtime.CompilerServices;
+using System.Text.Json;
+using System.Text.Json.Nodes;
 using JsonApiDotNetCore.Configuration;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiMetadata;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.ResourceObjects;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SwaggerComponents;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -79,7 +80,7 @@ public DataSchemaGenerator(SchemaGenerationTracer schemaGenerationTracer, Schema
         _resourceDocumentationReader = resourceDocumentationReader;
     }
 
-    public OpenApiSchema GenerateSchema(Type dataSchemaType, bool forRequestSchema, SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchema(Type dataSchemaType, bool forRequestSchema, SchemaRepository schemaRepository)
     {
         // For a given resource (identifier) type, we always generate the full type hierarchy. Discriminator mappings
         // are managed manually, because there's no way to intercept in the Swashbuckle recursive component schema generation.
@@ -87,7 +88,7 @@ public OpenApiSchema GenerateSchema(Type dataSchemaType, bool forRequestSchema,
         ArgumentNullException.ThrowIfNull(dataSchemaType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        if (schemaRepository.TryLookupByType(dataSchemaType, out OpenApiSchema referenceSchemaForData))
+        if (schemaRepository.TryLookupByType(dataSchemaType, out OpenApiSchemaReference? referenceSchemaForData))
         {
             return referenceSchemaForData;
         }
@@ -114,11 +115,11 @@ public OpenApiSchema GenerateSchema(Type dataSchemaType, bool forRequestSchema,
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, dataSchemaType);
 
-        referenceSchemaForData = _defaultSchemaGenerator.GenerateSchema(dataSchemaType, schemaRepository);
-        OpenApiSchema fullSchemaForData = schemaRepository.Schemas[referenceSchemaForData.Reference.Id];
+        referenceSchemaForData = (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(dataSchemaType, schemaRepository);
+        var fullSchemaForData = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForData.Reference.Id!];
         fullSchemaForData.AdditionalPropertiesAllowed = false;
 
-        OpenApiSchema inlineSchemaForData = fullSchemaForData.UnwrapLastExtendedSchema();
+        var inlineSchemaForData = (OpenApiSchema)fullSchemaForData.UnwrapLastExtendedSchema();
 
         SetAbstract(inlineSchemaForData, resourceSchemaType);
         SetResourceType(inlineSchemaForData, resourceType, schemaRepository);
@@ -142,10 +143,11 @@ public OpenApiSchema GenerateSchema(Type dataSchemaType, bool forRequestSchema,
 
         if (RequiresRootObjectTypeInDataSchema(resourceSchemaType, forRequestSchema))
         {
-            fullSchemaForData.Extensions[SetSchemaTypeToObjectDocumentFilter.RequiresRootObjectTypeKey] = new OpenApiBoolean(true);
+            fullSchemaForData.Extensions ??= new Dictionary();
+            fullSchemaForData.Extensions[SetSchemaTypeToObjectDocumentFilter.RequiresRootObjectTypeKey] = new JsonNodeExtension(true);
         }
 
-        traceScope.TraceSucceeded(referenceSchemaForData.Reference.Id);
+        traceScope.TraceSucceeded(referenceSchemaForData.Reference.Id!);
         return referenceSchemaForData;
     }
 
@@ -202,39 +204,39 @@ public OpenApiSchema GenerateSchema(Type dataSchemaType, bool forRequestSchema,
         return boxedSchemaType.Value;
     }
 
-    public OpenApiSchema GenerateSchemaForCommonData(Type commonDataSchemaType, SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchemaForCommonData(Type commonDataSchemaType, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(commonDataSchemaType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        if (schemaRepository.TryLookupByType(commonDataSchemaType, out OpenApiSchema? referenceSchema))
+        if (schemaRepository.TryLookupByType(commonDataSchemaType, out OpenApiSchemaReference? referenceSchema))
         {
             return referenceSchema;
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, commonDataSchemaType);
 
-        OpenApiSchema referenceSchemaForResourceType = _resourceTypeSchemaGenerator.GenerateSchema(schemaRepository);
-        OpenApiSchema referenceSchemaForMeta = _metaSchemaGenerator.GenerateSchema(schemaRepository);
+        OpenApiSchemaReference referenceSchemaForResourceType = _resourceTypeSchemaGenerator.GenerateSchema(schemaRepository);
+        OpenApiSchemaReference referenceSchemaForMeta = _metaSchemaGenerator.GenerateSchema(schemaRepository);
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "object",
+            Type = JsonSchemaType.Object,
             Required = new SortedSet([JsonApiPropertyName.Type]),
-            Properties = new Dictionary
+            Properties = new Dictionary
             {
                 [JsonApiPropertyName.Type] = referenceSchemaForResourceType.WrapInExtendedSchema(),
-                [referenceSchemaForMeta.Reference.Id] = referenceSchemaForMeta.WrapInExtendedSchema()
+                [referenceSchemaForMeta.Reference.Id!] = referenceSchemaForMeta.WrapInExtendedSchema()
             },
             AdditionalPropertiesAllowed = false,
             Discriminator = new OpenApiDiscriminator
             {
                 PropertyName = JsonApiPropertyName.Type,
-                Mapping = new SortedDictionary(StringComparer.Ordinal)
+                Mapping = new SortedDictionary(StringComparer.Ordinal)
             },
-            Extensions =
+            Extensions = new SortedDictionary
             {
-                ["x-abstract"] = new OpenApiBoolean(true)
+                ["x-abstract"] = new JsonNodeExtension(true)
             }
         };
 
@@ -251,7 +253,7 @@ private static ResourceType GetUltimateBaseType(ResourceType resourceType)
     {
         return UltimateBaseResourceTypeCache.GetOrAdd(resourceType, type =>
         {
-            ResourceType baseType = type;
+            ResourceType? baseType = type;
 
             while (baseType.BaseType != null)
             {
@@ -272,15 +274,16 @@ private static void SetAbstract(OpenApiSchema fullSchema, ResourceSchemaType res
     {
         if (resourceSchemaType.ResourceType.ClrType.IsAbstract && resourceSchemaType.SchemaOpenType != typeof(IdentifierInRequest<>))
         {
-            fullSchema.Extensions["x-abstract"] = new OpenApiBoolean(true);
+            fullSchema.Extensions ??= new Dictionary();
+            fullSchema.Extensions["x-abstract"] = new JsonNodeExtension(true);
         }
     }
 
     private void SetResourceType(OpenApiSchema fullSchema, ResourceType resourceType, SchemaRepository schemaRepository)
     {
-        if (fullSchema.Properties.ContainsKey(JsonApiPropertyName.Type))
+        if (fullSchema.Properties != null && fullSchema.Properties.ContainsKey(JsonApiPropertyName.Type))
         {
-            OpenApiSchema referenceSchema = _resourceTypeSchemaGenerator.GenerateSchema(resourceType, schemaRepository);
+            OpenApiSchemaReference referenceSchema = _resourceTypeSchemaGenerator.GenerateSchema(resourceType, schemaRepository);
             fullSchema.Properties[JsonApiPropertyName.Type] = referenceSchema.WrapInExtendedSchema();
         }
     }
@@ -295,9 +298,12 @@ private void AdaptResourceIdentity(OpenApiSchema fullSchema, ResourceSchemaType
 
         bool hasAtomicOperationsEndpoint = _generationCacheSchemaGenerator.HasAtomicOperationsEndpoint(schemaRepository);
 
+        IDictionary fullSchemaProperties = fullSchema.Properties!;
+        ISet fullSchemaRequired = fullSchema.Required!;
+
         if (!hasAtomicOperationsEndpoint)
         {
-            fullSchema.Properties.Remove(JsonApiPropertyName.Lid);
+            fullSchemaProperties.Remove(JsonApiPropertyName.Lid);
         }
 
         if (resourceSchemaType.SchemaOpenType == typeof(DataInCreateRequest<>))
@@ -308,23 +314,23 @@ private void AdaptResourceIdentity(OpenApiSchema fullSchema, ResourceSchemaType
             {
                 if (clientIdGeneration == ClientIdGenerationMode.Forbidden)
                 {
-                    fullSchema.Properties.Remove(JsonApiPropertyName.Id);
+                    fullSchemaProperties.Remove(JsonApiPropertyName.Id);
                 }
                 else if (clientIdGeneration == ClientIdGenerationMode.Required)
                 {
-                    fullSchema.Properties.Remove(JsonApiPropertyName.Lid);
-                    fullSchema.Required.Add(JsonApiPropertyName.Id);
+                    fullSchemaProperties.Remove(JsonApiPropertyName.Lid);
+                    fullSchemaRequired.Add(JsonApiPropertyName.Id);
                 }
             }
             else
             {
                 if (clientIdGeneration == ClientIdGenerationMode.Forbidden)
                 {
-                    fullSchema.Properties.Remove(JsonApiPropertyName.Id);
+                    fullSchemaProperties.Remove(JsonApiPropertyName.Id);
                 }
                 else if (clientIdGeneration == ClientIdGenerationMode.Required)
                 {
-                    fullSchema.Required.Add(JsonApiPropertyName.Id);
+                    fullSchemaRequired.Add(JsonApiPropertyName.Id);
                 }
             }
         }
@@ -332,14 +338,14 @@ private void AdaptResourceIdentity(OpenApiSchema fullSchema, ResourceSchemaType
         {
             if (!hasAtomicOperationsEndpoint)
             {
-                fullSchema.Required.Add(JsonApiPropertyName.Id);
+                fullSchemaRequired.Add(JsonApiPropertyName.Id);
             }
         }
     }
 
     private void SetResourceId(OpenApiSchema fullSchema, ResourceType resourceType, SchemaRepository schemaRepository)
     {
-        if (fullSchema.Properties.ContainsKey(JsonApiPropertyName.Id))
+        if (fullSchema.Properties != null && fullSchema.Properties.ContainsKey(JsonApiPropertyName.Id))
         {
             OpenApiSchema idSchema = _resourceIdSchemaGenerator.GenerateSchema(resourceType, schemaRepository);
             fullSchema.Properties[JsonApiPropertyName.Id] = idSchema;
@@ -349,7 +355,7 @@ private void SetResourceId(OpenApiSchema fullSchema, ResourceType resourceType,
     private void SetResourceFields(OpenApiSchema fullSchemaForData, ResourceSchemaType resourceSchemaType, bool forRequestSchema,
         SchemaRepository schemaRepository)
     {
-        bool schemaHasFields = fullSchemaForData.Properties.ContainsKey(JsonApiPropertyName.Attributes) &&
+        bool schemaHasFields = fullSchemaForData.Properties != null && fullSchemaForData.Properties.ContainsKey(JsonApiPropertyName.Attributes) &&
             fullSchemaForData.Properties.ContainsKey(JsonApiPropertyName.Relationships);
 
         if (schemaHasFields)
@@ -367,8 +373,8 @@ private void SetFieldSchemaMembers(OpenApiSchema fullSchemaForData, ResourceSche
     {
         string propertyNameInSchema = forAttributes ? JsonApiPropertyName.Attributes : JsonApiPropertyName.Relationships;
 
-        OpenApiSchema referenceSchemaForFields = fullSchemaForData.Properties[propertyNameInSchema].UnwrapLastExtendedSchema();
-        OpenApiSchema fullSchemaForFields = schemaRepository.Schemas[referenceSchemaForFields.Reference.Id];
+        var referenceSchemaForFields = (OpenApiSchemaReference)fullSchemaForData.Properties![propertyNameInSchema].UnwrapLastExtendedSchema();
+        var fullSchemaForFields = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForFields.Reference.Id!];
         fullSchemaForFields.AdditionalPropertiesAllowed = false;
 
         SetAbstract(fullSchemaForFields, resourceSchemaTypeForData);
@@ -382,10 +388,10 @@ private void SetFieldSchemaMembers(OpenApiSchema fullSchemaForData, ResourceSche
             fieldSchemaBuilder.SetMembersOfRelationships(fullSchemaForFields, forRequestSchema, schemaRepository);
         }
 
-        if (fullSchemaForFields.Properties.Count == 0 && !resourceSchemaTypeForData.ResourceType.IsPartOfTypeHierarchy())
+        if (fullSchemaForFields.Properties is { Count: 0 } && !resourceSchemaTypeForData.ResourceType.IsPartOfTypeHierarchy())
         {
             fullSchemaForData.Properties.Remove(propertyNameInSchema);
-            schemaRepository.Schemas.Remove(referenceSchemaForFields.Reference.Id);
+            schemaRepository.Schemas.Remove(referenceSchemaForFields.Reference.Id!);
         }
         else
         {
@@ -414,9 +420,9 @@ private void SetFieldSchemaMembers(OpenApiSchema fullSchemaForData, ResourceSche
                 baseSchemaType = commonFieldsSchemaType;
             }
 
-            OpenApiSchema referenceSchemaForBase = schemaRepository.LookupByType(baseSchemaType);
+            OpenApiSchemaReference referenceSchemaForBase = schemaRepository.LookupByType(baseSchemaType);
 
-            schemaRepository.Schemas[referenceSchemaForFields.Reference.Id] = new OpenApiSchema
+            schemaRepository.Schemas[referenceSchemaForFields.Reference.Id!] = new OpenApiSchema
             {
                 AllOf =
                 [
@@ -437,22 +443,22 @@ private ResourceSchemaType GetResourceSchemaTypeForFieldsProperty(ResourceSchema
         return ResourceSchemaType.Create(fieldsConstructedType, _resourceGraph);
     }
 
-    private OpenApiSchema GenerateSchemaForCommonFields(Type commonFieldsSchemaType, SchemaRepository schemaRepository)
+    private OpenApiSchemaReference GenerateSchemaForCommonFields(Type commonFieldsSchemaType, SchemaRepository schemaRepository)
     {
-        if (schemaRepository.TryLookupByType(commonFieldsSchemaType, out OpenApiSchema? referenceSchema))
+        if (schemaRepository.TryLookupByType(commonFieldsSchemaType, out OpenApiSchemaReference? referenceSchema))
         {
             return referenceSchema;
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, commonFieldsSchemaType);
 
-        OpenApiSchema referenceSchemaForResourceType = _resourceTypeSchemaGenerator.GenerateSchema(schemaRepository);
+        OpenApiSchemaReference referenceSchemaForResourceType = _resourceTypeSchemaGenerator.GenerateSchema(schemaRepository);
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "object",
+            Type = JsonSchemaType.Object,
             Required = new SortedSet([OpenApiMediaTypeExtension.FullyQualifiedOpenApiDiscriminatorPropertyName]),
-            Properties = new Dictionary
+            Properties = new Dictionary
             {
                 [OpenApiMediaTypeExtension.FullyQualifiedOpenApiDiscriminatorPropertyName] = referenceSchemaForResourceType.WrapInExtendedSchema()
             },
@@ -460,11 +466,11 @@ private OpenApiSchema GenerateSchemaForCommonFields(Type commonFieldsSchemaType,
             Discriminator = new OpenApiDiscriminator
             {
                 PropertyName = OpenApiMediaTypeExtension.FullyQualifiedOpenApiDiscriminatorPropertyName,
-                Mapping = new SortedDictionary(StringComparer.Ordinal)
+                Mapping = new SortedDictionary(StringComparer.Ordinal)
             },
-            Extensions =
+            Extensions = new SortedDictionary
             {
-                ["x-abstract"] = new OpenApiBoolean(true)
+                ["x-abstract"] = new JsonNodeExtension(true)
             }
         };
 
@@ -480,7 +486,7 @@ private OpenApiSchema GenerateSchemaForCommonFields(Type commonFieldsSchemaType,
     private void MapInDiscriminator(ResourceSchemaType resourceSchemaType, bool forRequestSchema, string discriminatorPropertyName,
         SchemaRepository schemaRepository)
     {
-        OpenApiSchema referenceSchemaForDerived = schemaRepository.LookupByType(resourceSchemaType.SchemaConstructedType);
+        OpenApiSchemaReference referenceSchemaForDerived = schemaRepository.LookupByType(resourceSchemaType.SchemaConstructedType);
 
         foreach (ResourceType? baseResourceType in GetBaseTypesToMapInto(resourceSchemaType, forRequestSchema))
         {
@@ -488,23 +494,25 @@ private void MapInDiscriminator(ResourceSchemaType resourceSchemaType, bool forR
                 ? GetCommonSchemaType(resourceSchemaType.SchemaOpenType)!
                 : resourceSchemaType.ChangeResourceType(baseResourceType).SchemaConstructedType;
 
-            OpenApiSchema referenceSchemaForBase = schemaRepository.LookupByType(baseSchemaType);
-            OpenApiSchema inlineSchemaForBase = schemaRepository.Schemas[referenceSchemaForBase.Reference.Id].UnwrapLastExtendedSchema();
+            OpenApiSchemaReference referenceSchemaForBase = schemaRepository.LookupByType(baseSchemaType);
+            var inlineSchemaForBase = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForBase.Reference.Id!].UnwrapLastExtendedSchema();
 
             inlineSchemaForBase.Discriminator ??= new OpenApiDiscriminator
             {
                 PropertyName = discriminatorPropertyName,
-                Mapping = new SortedDictionary(StringComparer.Ordinal)
+                Mapping = new SortedDictionary(StringComparer.Ordinal)
             };
 
             if (RepeatDiscriminatorInResponseDerivedTypes && !forRequestSchema)
             {
+                inlineSchemaForBase.Required ??= new SortedSet();
                 inlineSchemaForBase.Required.Add(discriminatorPropertyName);
             }
 
             string publicName = resourceSchemaType.ResourceType.PublicName;
+            inlineSchemaForBase.Discriminator.Mapping ??= new SortedDictionary();
 
-            if (inlineSchemaForBase.Discriminator.Mapping.TryAdd(publicName, referenceSchemaForDerived.Reference.ReferenceV3) && baseResourceType == null)
+            if (inlineSchemaForBase.Discriminator.Mapping.TryAdd(publicName, referenceSchemaForDerived) && baseResourceType == null)
             {
                 MapResourceTypeInEnum(publicName, schemaRepository);
             }
@@ -543,11 +551,13 @@ private void MapInDiscriminator(ResourceSchemaType resourceSchemaType, bool forR
     private void MapResourceTypeInEnum(string publicName, SchemaRepository schemaRepository)
     {
         string schemaId = _schemaIdSelector.GetResourceTypeSchemaId(null);
-        OpenApiSchema fullSchema = schemaRepository.Schemas[schemaId];
+        var fullSchema = (OpenApiSchema)schemaRepository.Schemas[schemaId];
+        fullSchema.Enum ??= [];
 
-        if (!fullSchema.Enum.Any(openApiAny => openApiAny is OpenApiString openApiString && openApiString.Value == publicName))
+        if (!fullSchema.Enum.Any(openApiAny => openApiAny is JsonValue openApiString && openApiString.GetValueKind() == JsonValueKind.String &&
+            openApiString.GetValue() == publicName))
         {
-            fullSchema.Enum.Add(new OpenApiString(publicName));
+            fullSchema.Enum.Add(publicName);
         }
     }
 
@@ -563,7 +573,7 @@ private void SetLinksVisibility(OpenApiSchema fullSchema, ResourceSchemaType res
 
     private void GenerateDataSchemasForDirectlyDerivedTypes(ResourceSchemaType resourceSchemaType, bool forRequestSchema, SchemaRepository schemaRepository)
     {
-        OpenApiSchema referenceSchemaForBase = schemaRepository.LookupByType(resourceSchemaType.SchemaConstructedType);
+        OpenApiSchemaReference referenceSchemaForBase = schemaRepository.LookupByType(resourceSchemaType.SchemaConstructedType);
 
         foreach (ResourceType derivedType in resourceSchemaType.ResourceType.DirectlyDerivedTypes)
         {
@@ -572,18 +582,18 @@ private void GenerateDataSchemasForDirectlyDerivedTypes(ResourceSchemaType resou
 
             using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, resourceSchemaTypeForDerived.SchemaConstructedType);
 
-            OpenApiSchema referenceSchemaForDerived = _defaultSchemaGenerator.GenerateSchema(derivedSchemaType, schemaRepository);
-            OpenApiSchema fullSchemaForDerived = schemaRepository.Schemas[referenceSchemaForDerived.Reference.Id];
+            var referenceSchemaForDerived = (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(derivedSchemaType, schemaRepository);
+            var fullSchemaForDerived = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForDerived.Reference.Id!];
             fullSchemaForDerived.AdditionalPropertiesAllowed = false;
 
-            OpenApiSchema inlineSchemaForDerived = fullSchemaForDerived.UnwrapLastExtendedSchema();
+            var inlineSchemaForDerived = (OpenApiSchema)fullSchemaForDerived.UnwrapLastExtendedSchema();
             SetResourceFields(inlineSchemaForDerived, resourceSchemaTypeForDerived, forRequestSchema, schemaRepository);
 
             SetAbstract(inlineSchemaForDerived, resourceSchemaTypeForDerived);
             RemoveProperties(inlineSchemaForDerived);
             MapInDiscriminator(resourceSchemaTypeForDerived, forRequestSchema, JsonApiPropertyName.Type, schemaRepository);
 
-            if (fullSchemaForDerived.AllOf.Count == 0)
+            if (fullSchemaForDerived.AllOf == null || fullSchemaForDerived.AllOf.Count == 0)
             {
                 var compositeSchemaForDerived = new OpenApiSchema
                 {
@@ -595,7 +605,7 @@ private void GenerateDataSchemasForDirectlyDerivedTypes(ResourceSchemaType resou
                     AdditionalPropertiesAllowed = false
                 };
 
-                schemaRepository.Schemas[referenceSchemaForDerived.Reference.Id] = compositeSchemaForDerived;
+                schemaRepository.Schemas[referenceSchemaForDerived.Reference.Id!] = compositeSchemaForDerived;
             }
             else
             {
@@ -604,22 +614,26 @@ private void GenerateDataSchemasForDirectlyDerivedTypes(ResourceSchemaType resou
 
             if (RequiresRootObjectTypeInDataSchema(resourceSchemaTypeForDerived, forRequestSchema))
             {
-                OpenApiSchema fullSchemaForData = schemaRepository.Schemas[referenceSchemaForDerived.Reference.Id];
-                fullSchemaForData.Extensions[SetSchemaTypeToObjectDocumentFilter.RequiresRootObjectTypeKey] = new OpenApiBoolean(true);
+                var fullSchemaForData = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForDerived.Reference.Id!];
+                fullSchemaForData.Extensions ??= new Dictionary();
+                fullSchemaForData.Extensions[SetSchemaTypeToObjectDocumentFilter.RequiresRootObjectTypeKey] = new JsonNodeExtension(true);
             }
 
             GenerateDataSchemasForDirectlyDerivedTypes(resourceSchemaTypeForDerived, forRequestSchema, schemaRepository);
 
-            traceScope.TraceSucceeded(referenceSchemaForDerived.Reference.Id);
+            traceScope.TraceSucceeded(referenceSchemaForDerived.Reference.Id!);
         }
     }
 
     private static void RemoveProperties(OpenApiSchema fullSchema)
     {
-        foreach (string propertyName in fullSchema.Properties.Keys)
+        if (fullSchema.Properties != null)
         {
-            fullSchema.Properties.Remove(propertyName);
-            fullSchema.Required.Remove(propertyName);
+            foreach (string propertyName in fullSchema.Properties.Keys)
+            {
+                fullSchema.Properties.Remove(propertyName);
+                fullSchema.Required?.Remove(propertyName);
+            }
         }
     }
 
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/LinksVisibilitySchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/LinksVisibilitySchemaGenerator.cs
index 5c099a3fc1..a0a5a1a065 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/LinksVisibilitySchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/LinksVisibilitySchemaGenerator.cs
@@ -4,7 +4,7 @@
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.ResourceObjects;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SwaggerComponents;
 using JsonApiDotNetCore.Resources.Annotations;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -110,32 +110,32 @@ public void UpdateSchemaForRelationship(Type schemaType, OpenApiSchema fullSchem
     private void UpdateLinksProperty(OpenApiSchema fullSchemaForLinksContainer, LinkTypes visibleLinkTypes, LinkTypes possibleLinkTypes,
         SchemaRepository schemaRepository)
     {
-        OpenApiSchema referenceSchemaForLinks = fullSchemaForLinksContainer.Properties[JsonApiPropertyName.Links].UnwrapLastExtendedSchema();
+        var referenceSchemaForLinks = (OpenApiSchemaReference)fullSchemaForLinksContainer.Properties![JsonApiPropertyName.Links].UnwrapLastExtendedSchema();
 
         if ((visibleLinkTypes & possibleLinkTypes) == 0)
         {
-            fullSchemaForLinksContainer.Required.Remove(JsonApiPropertyName.Links);
+            fullSchemaForLinksContainer.Required?.Remove(JsonApiPropertyName.Links);
             fullSchemaForLinksContainer.Properties.Remove(JsonApiPropertyName.Links);
 
-            schemaRepository.Schemas.Remove(referenceSchemaForLinks.Reference.Id);
+            schemaRepository.Schemas.Remove(referenceSchemaForLinks.Reference.Id!);
         }
         else if (visibleLinkTypes != possibleLinkTypes)
         {
-            string linksSchemaId = referenceSchemaForLinks.Reference.Id;
+            string linksSchemaId = referenceSchemaForLinks.Reference.Id!;
 
-            if (schemaRepository.Schemas.TryGetValue(linksSchemaId, out OpenApiSchema? fullSchemaForLinks))
+            if (schemaRepository.Schemas.TryGetValue(linksSchemaId, out IOpenApiSchema? fullSchemaForLinks))
             {
                 UpdateLinkProperties(fullSchemaForLinks, visibleLinkTypes);
             }
         }
     }
 
-    private void UpdateLinkProperties(OpenApiSchema fullSchemaForLinks, LinkTypes availableLinkTypes)
+    private void UpdateLinkProperties(IOpenApiSchema fullSchemaForLinks, LinkTypes availableLinkTypes)
     {
         foreach (string propertyName in LinkTypeToPropertyNamesMap.Where(pair => !availableLinkTypes.HasFlag(pair.Key)).SelectMany(pair => pair.Value))
         {
-            fullSchemaForLinks.Required.Remove(propertyName);
-            fullSchemaForLinks.Properties.Remove(propertyName);
+            fullSchemaForLinks.Required?.Remove(propertyName);
+            fullSchemaForLinks.Properties?.Remove(propertyName);
         }
     }
 
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/MetaSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/MetaSchemaGenerator.cs
index 1e1bd07852..8b2c200ea7 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/MetaSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/MetaSchemaGenerator.cs
@@ -1,5 +1,5 @@
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -19,11 +19,11 @@ public MetaSchemaGenerator(SchemaGenerationTracer schemaGenerationTracer, JsonAp
         _schemaIdSelector = schemaIdSelector;
     }
 
-    public OpenApiSchema GenerateSchema(SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchema(SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        if (schemaRepository.TryLookupByType(SchemaType, out OpenApiSchema? referenceSchema))
+        if (schemaRepository.TryLookupByType(SchemaType, out OpenApiSchemaReference? referenceSchema))
         {
             return referenceSchema;
         }
@@ -32,10 +32,10 @@ public OpenApiSchema GenerateSchema(SchemaRepository schemaRepository)
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "object",
+            Type = JsonSchemaType.Object,
             AdditionalProperties = new OpenApiSchema
             {
-                Nullable = true
+                Type = JsonSchemaType.Null
             }
         };
 
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipIdentifierSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipIdentifierSchemaGenerator.cs
index 98f176e8df..716bdc09be 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipIdentifierSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipIdentifierSchemaGenerator.cs
@@ -1,7 +1,7 @@
 using JsonApiDotNetCore.Configuration;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.ResourceObjects;
 using JsonApiDotNetCore.Resources.Annotations;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -34,7 +34,7 @@ public RelationshipIdentifierSchemaGenerator(SchemaGenerationTracer schemaGenera
         _schemaIdSelector = schemaIdSelector;
     }
 
-    public OpenApiSchema GenerateSchema(RelationshipAttribute relationship, SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchema(RelationshipAttribute relationship, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(relationship);
         ArgumentNullException.ThrowIfNull(schemaRepository);
@@ -43,14 +43,7 @@ public OpenApiSchema GenerateSchema(RelationshipAttribute relationship, SchemaRe
 
         if (schemaRepository.Schemas.ContainsKey(schemaId))
         {
-            return new OpenApiSchema
-            {
-                Reference = new OpenApiReference
-                {
-                    Id = schemaId,
-                    Type = ReferenceType.Schema
-                }
-            };
+            return new OpenApiSchemaReference(schemaId);
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, relationship);
@@ -58,17 +51,19 @@ public OpenApiSchema GenerateSchema(RelationshipAttribute relationship, SchemaRe
         Type relationshipIdentifierConstructedType = typeof(RelationshipIdentifier<>).MakeGenericType(relationship.LeftType.ClrType);
         ConsistencyGuard.ThrowIf(schemaRepository.TryLookupByType(relationshipIdentifierConstructedType, out _));
 
-        OpenApiSchema referenceSchemaForIdentifier = _defaultSchemaGenerator.GenerateSchema(relationshipIdentifierConstructedType, schemaRepository);
-        OpenApiSchema fullSchemaForIdentifier = schemaRepository.Schemas[referenceSchemaForIdentifier.Reference.Id];
+        var referenceSchemaForIdentifier =
+            (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(relationshipIdentifierConstructedType, schemaRepository);
 
-        fullSchemaForIdentifier.Properties.Remove(JsonApiPropertyName.Meta);
+        var fullSchemaForIdentifier = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForIdentifier.Reference.Id!];
+
+        fullSchemaForIdentifier.Properties?.Remove(JsonApiPropertyName.Meta);
 
         SetResourceType(fullSchemaForIdentifier, relationship.LeftType, schemaRepository);
         SetResourceId(fullSchemaForIdentifier, relationship.LeftType, schemaRepository);
         SetRelationship(fullSchemaForIdentifier, relationship, schemaRepository);
 
         schemaRepository.ReplaceSchemaId(relationshipIdentifierConstructedType, schemaId);
-        referenceSchemaForIdentifier.Reference.Id = schemaId;
+        referenceSchemaForIdentifier = new OpenApiSchemaReference(schemaId);
 
         traceScope.TraceSucceeded(schemaId);
         return referenceSchemaForIdentifier;
@@ -76,19 +71,22 @@ public OpenApiSchema GenerateSchema(RelationshipAttribute relationship, SchemaRe
 
     private void SetResourceType(OpenApiSchema fullSchemaForIdentifier, ResourceType resourceType, SchemaRepository schemaRepository)
     {
-        OpenApiSchema referenceSchema = _resourceTypeSchemaGenerator.GenerateSchema(resourceType, schemaRepository);
+        OpenApiSchemaReference referenceSchema = _resourceTypeSchemaGenerator.GenerateSchema(resourceType, schemaRepository);
+        fullSchemaForIdentifier.Properties ??= new Dictionary();
         fullSchemaForIdentifier.Properties[JsonApiPropertyName.Type] = referenceSchema.WrapInExtendedSchema();
     }
 
     private void SetResourceId(OpenApiSchema fullSchemaForResourceData, ResourceType resourceType, SchemaRepository schemaRepository)
     {
         OpenApiSchema idSchema = _resourceIdSchemaGenerator.GenerateSchema(resourceType, schemaRepository);
+        fullSchemaForResourceData.Properties ??= new Dictionary();
         fullSchemaForResourceData.Properties[JsonApiPropertyName.Id] = idSchema;
     }
 
     private void SetRelationship(OpenApiSchema fullSchemaForIdentifier, RelationshipAttribute relationship, SchemaRepository schemaRepository)
     {
-        OpenApiSchema referenceSchema = _relationshipNameSchemaGenerator.GenerateSchema(relationship, schemaRepository);
+        OpenApiSchemaReference referenceSchema = _relationshipNameSchemaGenerator.GenerateSchema(relationship, schemaRepository);
+        fullSchemaForIdentifier.Properties ??= new Dictionary();
         fullSchemaForIdentifier.Properties[JsonApiPropertyName.Relationship] = referenceSchema.WrapInExtendedSchema();
     }
 }
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipNameSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipNameSchemaGenerator.cs
index 7f5c0c5d3a..a3dbed6442 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipNameSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipNameSchemaGenerator.cs
@@ -1,6 +1,5 @@
 using JsonApiDotNetCore.Resources.Annotations;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -19,7 +18,7 @@ public RelationshipNameSchemaGenerator(SchemaGenerationTracer schemaGenerationTr
         _schemaIdSelector = schemaIdSelector;
     }
 
-    public OpenApiSchema GenerateSchema(RelationshipAttribute relationship, SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchema(RelationshipAttribute relationship, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(relationship);
         ArgumentNullException.ThrowIfNull(schemaRepository);
@@ -28,25 +27,18 @@ public OpenApiSchema GenerateSchema(RelationshipAttribute relationship, SchemaRe
 
         if (schemaRepository.Schemas.ContainsKey(schemaId))
         {
-            return new OpenApiSchema
-            {
-                Reference = new OpenApiReference
-                {
-                    Id = schemaId,
-                    Type = ReferenceType.Schema
-                }
-            };
+            return new OpenApiSchemaReference(schemaId);
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, relationship);
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "string",
-            Enum = [new OpenApiString(relationship.PublicName)]
+            Type = JsonSchemaType.String,
+            Enum = [relationship.PublicName]
         };
 
-        OpenApiSchema referenceSchema = schemaRepository.AddDefinition(schemaId, fullSchema);
+        OpenApiSchemaReference? referenceSchema = schemaRepository.AddDefinition(schemaId, fullSchema);
 
         traceScope.TraceSucceeded(schemaId);
         return referenceSchema;
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceIdSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceIdSchemaGenerator.cs
index f361db8183..9351af809c 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceIdSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceIdSchemaGenerator.cs
@@ -2,7 +2,7 @@
 using JsonApiDotNetCore.Configuration;
 using JsonApiDotNetCore.Middleware;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.Annotations;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -40,10 +40,10 @@ public OpenApiSchema GenerateSchema(ResourceType resourceType, SchemaRepository
         ArgumentNullException.ThrowIfNull(resourceType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        OpenApiSchema idSchema = _defaultSchemaGenerator.GenerateSchema(resourceType.IdentityClrType, schemaRepository);
-        ConsistencyGuard.ThrowIf(idSchema.Reference != null);
+        var idSchema = _defaultSchemaGenerator.GenerateSchema(resourceType.IdentityClrType, schemaRepository) as OpenApiSchema;
+        ConsistencyGuard.ThrowIf(idSchema == null);
 
-        idSchema.Type = "string";
+        idSchema.Type = JsonSchemaType.String;
 
         var hideIdTypeAttribute = resourceType.ClrType.GetCustomAttribute();
 
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceTypeSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceTypeSchemaGenerator.cs
index eb933bedbe..278ef5ae3c 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceTypeSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/ResourceTypeSchemaGenerator.cs
@@ -1,7 +1,6 @@
 using JsonApiDotNetCore.Configuration;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SwaggerComponents;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -20,12 +19,12 @@ public ResourceTypeSchemaGenerator(SchemaGenerationTracer schemaGenerationTracer
         _schemaIdSelector = schemaIdSelector;
     }
 
-    public OpenApiSchema GenerateSchema(ResourceType resourceType, SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchema(ResourceType resourceType, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(resourceType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        if (schemaRepository.TryLookupByType(resourceType.ClrType, out OpenApiSchema? referenceSchema))
+        if (schemaRepository.TryLookupByType(resourceType.ClrType, out OpenApiSchemaReference? referenceSchema))
         {
             return referenceSchema;
         }
@@ -34,17 +33,17 @@ public OpenApiSchema GenerateSchema(ResourceType resourceType, SchemaRepository
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "string",
-            Enum = resourceType.ClrType.IsAbstract ? [] : [new OpenApiString(resourceType.PublicName)],
-            Extensions =
+            Type = JsonSchemaType.String,
+            Enum = resourceType.ClrType.IsAbstract ? [] : [resourceType.PublicName],
+            Extensions = new SortedDictionary
             {
-                [StringEnumOrderingFilter.RequiresSortKey] = new OpenApiBoolean(true)
+                [StringEnumOrderingFilter.RequiresSortKey] = new JsonNodeExtension(true)
             }
         };
 
         foreach (ResourceType derivedType in resourceType.GetAllConcreteDerivedTypes())
         {
-            fullSchema.Enum.Add(new OpenApiString(derivedType.PublicName));
+            fullSchema.Enum.Add(derivedType.PublicName);
         }
 
         string schemaId = _schemaIdSelector.GetResourceTypeSchemaId(resourceType);
@@ -56,34 +55,27 @@ public OpenApiSchema GenerateSchema(ResourceType resourceType, SchemaRepository
         return referenceSchema;
     }
 
-    public OpenApiSchema GenerateSchema(SchemaRepository schemaRepository)
+    public OpenApiSchemaReference GenerateSchema(SchemaRepository schemaRepository)
     {
         string schemaId = _schemaIdSelector.GetResourceTypeSchemaId(null);
 
         if (schemaRepository.Schemas.ContainsKey(schemaId))
         {
-            return new OpenApiSchema
-            {
-                Reference = new OpenApiReference
-                {
-                    Id = schemaId,
-                    Type = ReferenceType.Schema
-                }
-            };
+            return new OpenApiSchemaReference(schemaId);
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this);
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "string",
-            Extensions =
+            Type = JsonSchemaType.String,
+            Extensions = new SortedDictionary
             {
-                [StringEnumOrderingFilter.RequiresSortKey] = new OpenApiBoolean(true)
+                [StringEnumOrderingFilter.RequiresSortKey] = new JsonNodeExtension(true)
             }
         };
 
-        OpenApiSchema referenceSchema = schemaRepository.AddDefinition(schemaId, fullSchema);
+        OpenApiSchemaReference? referenceSchema = schemaRepository.AddDefinition(schemaId, fullSchema);
 
         traceScope.TraceSucceeded(schemaId);
         return referenceSchema;
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/AtomicOperationsDocumentSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/AtomicOperationsDocumentSchemaGenerator.cs
index 648831fcbb..0750e52079 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/AtomicOperationsDocumentSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/AtomicOperationsDocumentSchemaGenerator.cs
@@ -7,8 +7,7 @@
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
 using JsonApiDotNetCore.Resources.Annotations;
 using JsonApiDotNetCore.Serialization.Objects;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Documents;
@@ -68,7 +67,7 @@ public override bool CanGenerate(Type schemaType)
         return schemaType == typeof(OperationsRequestDocument) || schemaType == typeof(OperationsResponseDocument);
     }
 
-    protected override OpenApiSchema GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository)
+    protected override OpenApiSchemaReference GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(schemaType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
@@ -84,7 +83,7 @@ protected override OpenApiSchema GenerateDocumentSchema(Type schemaType, SchemaR
             GenerateSchemasForResponseDocument(schemaRepository);
         }
 
-        return _defaultSchemaGenerator.GenerateSchema(schemaType, schemaRepository);
+        return (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(schemaType, schemaRepository);
     }
 
     private void GenerateSchemasForRequestDocument(SchemaRepository schemaRepository)
@@ -97,38 +96,38 @@ private void GenerateSchemasForRequestDocument(SchemaRepository schemaRepository
         }
     }
 
-    private OpenApiSchema GenerateSchemaForAbstractOperation(SchemaRepository schemaRepository)
+    private OpenApiSchemaReference GenerateSchemaForAbstractOperation(SchemaRepository schemaRepository)
     {
-        if (schemaRepository.TryLookupByType(AtomicOperationAbstractType, out OpenApiSchema? referenceSchema))
+        if (schemaRepository.TryLookupByType(AtomicOperationAbstractType, out OpenApiSchemaReference? referenceSchema))
         {
             return referenceSchema;
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, AtomicOperationAbstractType);
 
-        OpenApiSchema referenceSchemaForMeta = _metaSchemaGenerator.GenerateSchema(schemaRepository);
+        OpenApiSchemaReference referenceSchemaForMeta = _metaSchemaGenerator.GenerateSchema(schemaRepository);
 
         var fullSchema = new OpenApiSchema
         {
-            Type = "object",
+            Type = JsonSchemaType.Object,
             Required = new SortedSet([OpenApiMediaTypeExtension.FullyQualifiedOpenApiDiscriminatorPropertyName]),
-            Properties = new Dictionary
+            Properties = new Dictionary
             {
-                [OpenApiMediaTypeExtension.FullyQualifiedOpenApiDiscriminatorPropertyName] = new()
+                [OpenApiMediaTypeExtension.FullyQualifiedOpenApiDiscriminatorPropertyName] = new OpenApiSchema
                 {
-                    Type = "string"
+                    Type = JsonSchemaType.String
                 },
-                [referenceSchemaForMeta.Reference.Id] = referenceSchemaForMeta.WrapInExtendedSchema()
+                [referenceSchemaForMeta.Reference.Id!] = referenceSchemaForMeta.WrapInExtendedSchema()
             },
             AdditionalPropertiesAllowed = false,
             Discriminator = new OpenApiDiscriminator
             {
                 PropertyName = OpenApiMediaTypeExtension.FullyQualifiedOpenApiDiscriminatorPropertyName,
-                Mapping = new SortedDictionary(StringComparer.Ordinal)
+                Mapping = new SortedDictionary(StringComparer.Ordinal)
             },
-            Extensions =
+            Extensions = new SortedDictionary
             {
-                ["x-abstract"] = new OpenApiBoolean(true)
+                ["x-abstract"] = new JsonNodeExtension(true)
             }
         };
 
@@ -188,17 +187,18 @@ private void GenerateSchemaForResourceOperation(Type operationOpenType, Resource
                 }
             }
 
-            OpenApiSchema referenceSchemaForOperation = _defaultSchemaGenerator.GenerateSchema(operationConstructedType, schemaRepository);
-            OpenApiSchema fullSchemaForOperation = schemaRepository.Schemas[referenceSchemaForOperation.Reference.Id];
+            var referenceSchemaForOperation = (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(operationConstructedType, schemaRepository);
+            var fullSchemaForOperation = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForOperation.Reference.Id!];
             fullSchemaForOperation.AdditionalPropertiesAllowed = false;
-            OpenApiSchema inlineSchemaForOperation = fullSchemaForOperation.UnwrapLastExtendedSchema();
+            var inlineSchemaForOperation = (OpenApiSchema)fullSchemaForOperation.UnwrapLastExtendedSchema();
 
             if (needsEmptyDerivedSchema)
             {
                 Type baseOperationSchemaType = ChangeResourceTypeInSchemaType(operationOpenType, resourceType.BaseType!);
-                OpenApiSchema referenceSchemaForBaseOperation = schemaRepository.LookupByType(baseOperationSchemaType);
+                OpenApiSchemaReference referenceSchemaForBaseOperation = schemaRepository.LookupByType(baseOperationSchemaType);
 
                 RemoveProperties(inlineSchemaForOperation);
+                fullSchemaForOperation.AllOf ??= [];
                 fullSchemaForOperation.AllOf[0] = referenceSchemaForBaseOperation;
             }
             else
@@ -208,7 +208,7 @@ private void GenerateSchemaForResourceOperation(Type operationOpenType, Resource
 
             MapInDiscriminator(referenceSchemaForOperation, schemaRepository);
 
-            traceScope.TraceSucceeded(referenceSchemaForOperation.Reference.Id);
+            traceScope.TraceSucceeded(referenceSchemaForOperation.Reference.Id!);
         }
 
         foreach (ResourceType derivedType in resourceType.DirectlyDerivedTypes)
@@ -250,24 +250,30 @@ private static Type ChangeResourceTypeInSchemaType(Type schemaOpenType, Resource
 
     private static void RemoveProperties(OpenApiSchema fullSchema)
     {
-        foreach (string propertyName in fullSchema.Properties.Keys)
+        if (fullSchema.Properties != null)
         {
-            fullSchema.Properties.Remove(propertyName);
-            fullSchema.Required.Remove(propertyName);
+            foreach (string propertyName in fullSchema.Properties.Keys)
+            {
+                fullSchema.Properties.Remove(propertyName);
+                fullSchema.Required?.Remove(propertyName);
+            }
         }
     }
 
     private void SetOperationCode(OpenApiSchema fullSchema, AtomicOperationCode operationCode, SchemaRepository schemaRepository)
     {
-        OpenApiSchema referenceSchema = _atomicOperationCodeSchemaGenerator.GenerateSchema(operationCode, schemaRepository);
+        var referenceSchema = (OpenApiSchemaReference)_atomicOperationCodeSchemaGenerator.GenerateSchema(operationCode, schemaRepository);
+        fullSchema.Properties ??= new Dictionary();
         fullSchema.Properties[JsonApiPropertyName.Op] = referenceSchema.WrapInExtendedSchema();
     }
 
-    private static void MapInDiscriminator(OpenApiSchema referenceSchemaForOperation, SchemaRepository schemaRepository)
+    private static void MapInDiscriminator(OpenApiSchemaReference referenceSchemaForOperation, SchemaRepository schemaRepository)
     {
-        OpenApiSchema referenceSchemaForAbstractOperation = schemaRepository.LookupByType(AtomicOperationAbstractType);
-        OpenApiSchema fullSchemaForAbstractOperation = schemaRepository.Schemas[referenceSchemaForAbstractOperation.Reference.Id];
-        fullSchemaForAbstractOperation.Discriminator.Mapping.Add(referenceSchemaForOperation.Reference.Id, referenceSchemaForOperation.Reference.ReferenceV3);
+        OpenApiSchemaReference referenceSchemaForAbstractOperation = schemaRepository.LookupByType(AtomicOperationAbstractType);
+        var fullSchemaForAbstractOperation = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForAbstractOperation.Reference.Id!];
+        fullSchemaForAbstractOperation.Discriminator ??= new OpenApiDiscriminator();
+        fullSchemaForAbstractOperation.Discriminator.Mapping ??= new SortedDictionary();
+        fullSchemaForAbstractOperation.Discriminator.Mapping.Add(referenceSchemaForOperation.Reference.Id!, referenceSchemaForOperation);
     }
 
     private static HashSet GetRelationshipsInTypeHierarchy(ResourceType baseType)
@@ -314,7 +320,7 @@ private void GenerateSchemaForRelationshipOperation(Type operationOpenType, Rela
 
         RelationshipAttribute? relationshipInAnyBaseResourceType = GetRelationshipEnabledInAnyBase(relationship, writeOperation);
 
-        OpenApiSchema? referenceSchemaForRelationshipIdentifier;
+        OpenApiSchemaReference? referenceSchemaForRelationshipIdentifier;
 
         if (relationshipInAnyBaseResourceType == null)
         {
@@ -336,22 +342,24 @@ private void GenerateSchemaForRelationshipOperation(Type operationOpenType, Rela
         // the relationship name because there's no runtime Type available for it.
         string schemaId = _schemaIdSelector.GetRelationshipAtomicOperationSchemaId(relationship, operationCode);
 
-        OpenApiSchema referenceSchemaForOperation = _defaultSchemaGenerator.GenerateSchema(operationConstructedType, schemaRepository);
-        OpenApiSchema fullSchemaForOperation = schemaRepository.Schemas[referenceSchemaForOperation.Reference.Id];
+        var referenceSchemaForOperation = (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(operationConstructedType, schemaRepository);
+        var fullSchemaForOperation = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForOperation.Reference.Id!];
         fullSchemaForOperation.AdditionalPropertiesAllowed = false;
 
-        OpenApiSchema inlineSchemaForOperation = fullSchemaForOperation.UnwrapLastExtendedSchema();
+        var inlineSchemaForOperation = (OpenApiSchema)fullSchemaForOperation.UnwrapLastExtendedSchema();
         SetOperationCode(inlineSchemaForOperation, operationCode, schemaRepository);
 
         if (referenceSchemaForRelationshipIdentifier != null)
         {
+            inlineSchemaForOperation.Properties ??= new Dictionary();
             inlineSchemaForOperation.Properties[JsonApiPropertyName.Ref] = referenceSchemaForRelationshipIdentifier.WrapInExtendedSchema();
         }
 
-        inlineSchemaForOperation.Properties[JsonApiPropertyName.Data].Nullable = _resourceFieldValidationMetadataProvider.IsNullable(relationship);
+        bool isNullable = _resourceFieldValidationMetadataProvider.IsNullable(relationship);
+        ((OpenApiSchema)inlineSchemaForOperation.Properties![JsonApiPropertyName.Data]).SetNullable(isNullable);
 
         schemaRepository.ReplaceSchemaId(operationConstructedType, schemaId);
-        referenceSchemaForOperation.Reference.Id = schemaId;
+        referenceSchemaForOperation = new OpenApiSchemaReference(schemaId);
 
         if (relationshipInAnyBaseResourceType != null)
         {
@@ -360,14 +368,8 @@ private void GenerateSchemaForRelationshipOperation(Type operationOpenType, Rela
             string baseRelationshipSchemaId = _schemaIdSelector.GetRelationshipAtomicOperationSchemaId(relationshipInAnyBaseResourceType, operationCode);
             ConsistencyGuard.ThrowIf(!schemaRepository.Schemas.ContainsKey(baseRelationshipSchemaId));
 
-            fullSchemaForOperation.AllOf[0] = new OpenApiSchema
-            {
-                Reference = new OpenApiReference
-                {
-                    Id = baseRelationshipSchemaId,
-                    Type = ReferenceType.Schema
-                }
-            };
+            fullSchemaForOperation.AllOf ??= [];
+            fullSchemaForOperation.AllOf[0] = new OpenApiSchemaReference(baseRelationshipSchemaId);
         }
 
         MapInDiscriminator(referenceSchemaForOperation, schemaRepository);
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/DocumentSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/DocumentSchemaGenerator.cs
index 740b2fca43..b801b2763e 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/DocumentSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/DocumentSchemaGenerator.cs
@@ -1,6 +1,6 @@
 using JsonApiDotNetCore.Configuration;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Documents;
@@ -31,12 +31,12 @@ protected DocumentSchemaGenerator(SchemaGenerationTracer schemaGenerationTracer,
 
     public abstract bool CanGenerate(Type schemaType);
 
-    public OpenApiSchema GenerateSchema(Type schemaType, SchemaRepository schemaRepository)
+    public IOpenApiSchema GenerateSchema(Type schemaType, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(schemaType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        if (schemaRepository.TryLookupByType(schemaType, out OpenApiSchema? referenceSchema))
+        if (schemaRepository.TryLookupByType(schemaType, out OpenApiSchemaReference? referenceSchema))
         {
             return referenceSchema;
         }
@@ -46,21 +46,21 @@ public OpenApiSchema GenerateSchema(Type schemaType, SchemaRepository schemaRepo
         _metaSchemaGenerator.GenerateSchema(schemaRepository);
 
         referenceSchema = GenerateDocumentSchema(schemaType, schemaRepository);
-        OpenApiSchema fullSchema = schemaRepository.Schemas[referenceSchema.Reference.Id];
+        var fullSchema = (OpenApiSchema)schemaRepository.Schemas[referenceSchema.Reference.Id!];
 
         _linksVisibilitySchemaGenerator.UpdateSchemaForTopLevel(schemaType, fullSchema, schemaRepository);
 
         SetJsonApiVersion(fullSchema, schemaRepository);
 
-        traceScope.TraceSucceeded(referenceSchema.Reference.Id);
+        traceScope.TraceSucceeded(referenceSchema.Reference.Id!);
         return referenceSchema;
     }
 
-    protected abstract OpenApiSchema GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository);
+    protected abstract OpenApiSchemaReference GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository);
 
     private void SetJsonApiVersion(OpenApiSchema fullSchema, SchemaRepository schemaRepository)
     {
-        if (fullSchema.Properties.ContainsKey(JsonApiPropertyName.Jsonapi) && !_options.IncludeJsonApiVersion)
+        if (fullSchema.Properties != null && fullSchema.Properties.ContainsKey(JsonApiPropertyName.Jsonapi) && !_options.IncludeJsonApiVersion)
         {
             fullSchema.Properties.Remove(JsonApiPropertyName.Jsonapi);
             schemaRepository.Schemas.Remove(JsonApiPropertyName.Jsonapi);
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ErrorResponseDocumentSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ErrorResponseDocumentSchemaGenerator.cs
index 3d305e889b..a132d747f3 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ErrorResponseDocumentSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ErrorResponseDocumentSchemaGenerator.cs
@@ -2,7 +2,7 @@
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.Documents;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
 using JsonApiDotNetCore.Serialization.Objects;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Documents;
@@ -34,27 +34,28 @@ public override bool CanGenerate(Type schemaType)
         return schemaType == typeof(ErrorResponseDocument);
     }
 
-    protected override OpenApiSchema GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository)
+    protected override OpenApiSchemaReference GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(schemaType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
 
-        OpenApiSchema referenceSchemaForErrorObject = GenerateSchemaForErrorObject(schemaRepository);
-        OpenApiSchema fullSchemaForErrorObject = schemaRepository.Schemas[referenceSchemaForErrorObject.Reference.Id];
+        OpenApiSchemaReference referenceSchemaForErrorObject = GenerateSchemaForErrorObject(schemaRepository);
+        var fullSchemaForErrorObject = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForErrorObject.Reference.Id!];
 
-        OpenApiSchema referenceSchemaForMeta = _metaSchemaGenerator.GenerateSchema(schemaRepository);
+        OpenApiSchemaReference referenceSchemaForMeta = _metaSchemaGenerator.GenerateSchema(schemaRepository);
+        fullSchemaForErrorObject.Properties ??= new Dictionary();
         fullSchemaForErrorObject.Properties[JsonApiPropertyName.Meta] = referenceSchemaForMeta.WrapInExtendedSchema();
 
-        return _defaultSchemaGenerator.GenerateSchema(schemaType, schemaRepository);
+        return (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(schemaType, schemaRepository);
     }
 
-    private OpenApiSchema GenerateSchemaForErrorObject(SchemaRepository schemaRepository)
+    private OpenApiSchemaReference GenerateSchemaForErrorObject(SchemaRepository schemaRepository)
     {
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this, ErrorObjectType);
 
-        OpenApiSchema referenceSchema = _defaultSchemaGenerator.GenerateSchema(ErrorObjectType, schemaRepository);
+        var referenceSchema = (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(ErrorObjectType, schemaRepository);
 
-        traceScope.TraceSucceeded(referenceSchema.Reference.Id);
+        traceScope.TraceSucceeded(referenceSchema.Reference.Id!);
         return referenceSchema;
     }
 }
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ResourceOrRelationshipDocumentSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ResourceOrRelationshipDocumentSchemaGenerator.cs
index 0762e5b8c1..64b25f8ae2 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ResourceOrRelationshipDocumentSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/ResourceOrRelationshipDocumentSchemaGenerator.cs
@@ -1,7 +1,7 @@
 using JsonApiDotNetCore.Configuration;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SwaggerComponents;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Documents;
@@ -34,7 +34,7 @@ public override bool CanGenerate(Type schemaType)
         return JsonApiSchemaFacts.IsRequestDocumentSchemaType(schemaType) || JsonApiSchemaFacts.IsResponseDocumentSchemaType(schemaType);
     }
 
-    protected override OpenApiSchema GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository)
+    protected override OpenApiSchemaReference GenerateDocumentSchema(Type schemaType, SchemaRepository schemaRepository)
     {
         ArgumentNullException.ThrowIfNull(schemaType);
         ArgumentNullException.ThrowIfNull(schemaRepository);
@@ -44,12 +44,13 @@ protected override OpenApiSchema GenerateDocumentSchema(Type schemaType, SchemaR
 
         _ = _dataContainerSchemaGenerator.GenerateSchema(schemaType, resourceSchemaType.ResourceType, isRequestSchema, !isRequestSchema, schemaRepository);
 
-        OpenApiSchema? referenceSchemaForDocument = _defaultSchemaGenerator.GenerateSchema(schemaType, schemaRepository);
-        OpenApiSchema inlineSchemaForDocument = schemaRepository.Schemas[referenceSchemaForDocument.Reference.Id].UnwrapLastExtendedSchema();
+        var referenceSchemaForDocument = (OpenApiSchemaReference)_defaultSchemaGenerator.GenerateSchema(schemaType, schemaRepository);
+        var inlineSchemaForDocument = (OpenApiSchema)schemaRepository.Schemas[referenceSchemaForDocument.Reference.Id!].UnwrapLastExtendedSchema();
 
         if (JsonApiSchemaFacts.HasNullableDataProperty(resourceSchemaType.SchemaOpenType))
         {
-            inlineSchemaForDocument.Properties[JsonApiPropertyName.Data].Nullable = true;
+            inlineSchemaForDocument.Properties ??= new Dictionary();
+            ((OpenApiSchema)inlineSchemaForDocument.Properties[JsonApiPropertyName.Data]).SetNullable(true);
         }
 
         return referenceSchemaForDocument;
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/GenerationCacheSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/GenerationCacheSchemaGenerator.cs
index d67203979a..1d720af300 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/GenerationCacheSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/GenerationCacheSchemaGenerator.cs
@@ -1,8 +1,7 @@
 using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiMetadata.ActionMethods;
 using Microsoft.AspNetCore.Mvc.Abstractions;
 using Microsoft.AspNetCore.Mvc.Infrastructure;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators;
@@ -33,30 +32,29 @@ public bool HasAtomicOperationsEndpoint(SchemaRepository schemaRepository)
 
         OpenApiSchema fullSchema = GenerateFullSchema(schemaRepository);
 
-        var hasAtomicOperationsEndpoint = (OpenApiBoolean)fullSchema.Properties[HasAtomicOperationsEndpointPropertyName].Default;
-        return hasAtomicOperationsEndpoint.Value;
+        return fullSchema.Properties != null && (bool)fullSchema.Properties[HasAtomicOperationsEndpointPropertyName].Default!;
     }
 
     private OpenApiSchema GenerateFullSchema(SchemaRepository schemaRepository)
     {
-        if (schemaRepository.Schemas.TryGetValue(SchemaId, out OpenApiSchema? fullSchema))
+        if (schemaRepository.Schemas.TryGetValue(SchemaId, out IOpenApiSchema? existingFullSchema))
         {
-            return fullSchema;
+            return (OpenApiSchema)existingFullSchema;
         }
 
         using ISchemaGenerationTraceScope traceScope = _schemaGenerationTracer.TraceStart(this);
 
         bool hasAtomicOperationsEndpoint = EvaluateHasAtomicOperationsEndpoint();
 
-        fullSchema = new OpenApiSchema
+        var fullSchema = new OpenApiSchema
         {
-            Type = "object",
-            Properties = new Dictionary
+            Type = JsonSchemaType.Object,
+            Properties = new Dictionary
             {
-                [HasAtomicOperationsEndpointPropertyName] = new()
+                [HasAtomicOperationsEndpointPropertyName] = new OpenApiSchema
                 {
-                    Type = "boolean",
-                    Default = new OpenApiBoolean(hasAtomicOperationsEndpoint)
+                    Type = JsonSchemaType.Boolean,
+                    Default = hasAtomicOperationsEndpoint
                 }
             }
         };
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/JsonApiSchemaGenerator.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/JsonApiSchemaGenerator.cs
index b8e1d9f053..281cd2b233 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/JsonApiSchemaGenerator.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/JsonApiSchemaGenerator.cs
@@ -3,7 +3,7 @@
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
 using JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Documents;
 using Microsoft.AspNetCore.Mvc.ApiExplorer;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators;
@@ -26,7 +26,7 @@ public JsonApiSchemaGenerator(SchemaGenerator defaultSchemaGenerator, ResourceId
         _documentSchemaGenerators = documentSchemaGenerators as DocumentSchemaGenerator[] ?? documentSchemaGenerators.ToArray();
     }
 
-    public OpenApiSchema GenerateSchema(Type schemaType, SchemaRepository schemaRepository, MemberInfo? memberInfo = null, ParameterInfo? parameterInfo = null,
+    public IOpenApiSchema GenerateSchema(Type schemaType, SchemaRepository schemaRepository, MemberInfo? memberInfo = null, ParameterInfo? parameterInfo = null,
         ApiParameterRouteInfo? routeInfo = null)
     {
         ArgumentNullException.ThrowIfNull(schemaType);
@@ -41,7 +41,7 @@ public OpenApiSchema GenerateSchema(Type schemaType, SchemaRepository schemaRepo
 
         if (schemaGenerator != null)
         {
-            OpenApiSchema referenceSchema = schemaGenerator.GenerateSchema(schemaType, schemaRepository);
+            IOpenApiSchema referenceSchema = schemaGenerator.GenerateSchema(schemaType, schemaRepository);
 
             if (memberInfo != null || parameterInfo != null)
             {
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaRepositoryExtensions.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaRepositoryExtensions.cs
index 669c50b4e0..eb0ee81617 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaRepositoryExtensions.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaRepositoryExtensions.cs
@@ -1,5 +1,5 @@
 using System.Reflection;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle;
@@ -28,12 +28,12 @@ private static FieldInfo GetReservedIdsField()
         return field;
     }
 
-    public static OpenApiSchema LookupByType(this SchemaRepository schemaRepository, Type schemaType)
+    public static OpenApiSchemaReference LookupByType(this SchemaRepository schemaRepository, Type schemaType)
     {
         ArgumentNullException.ThrowIfNull(schemaRepository);
         ArgumentNullException.ThrowIfNull(schemaType);
 
-        if (!schemaRepository.TryLookupByType(schemaType, out OpenApiSchema? referenceSchema))
+        if (!schemaRepository.TryLookupByType(schemaType, out OpenApiSchemaReference? referenceSchema))
         {
             throw new InvalidOperationException($"Reference schema for '{schemaType.Name}' does not exist.");
         }
@@ -47,11 +47,11 @@ public static void ReplaceSchemaId(this SchemaRepository schemaRepository, Type
         ArgumentNullException.ThrowIfNull(oldSchemaType);
         ArgumentException.ThrowIfNullOrEmpty(newSchemaId);
 
-        if (schemaRepository.TryLookupByType(oldSchemaType, out OpenApiSchema? referenceSchema))
+        if (schemaRepository.TryLookupByType(oldSchemaType, out OpenApiSchemaReference? referenceSchema))
         {
-            string oldSchemaId = referenceSchema.Reference.Id;
+            string oldSchemaId = referenceSchema.Reference.Id!;
 
-            OpenApiSchema fullSchema = schemaRepository.Schemas[oldSchemaId];
+            IOpenApiSchema? fullSchema = schemaRepository.Schemas[oldSchemaId];
 
             schemaRepository.Schemas.Remove(oldSchemaId);
             schemaRepository.Schemas.Add(newSchemaId, fullSchema);
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SetSchemaTypeToObjectDocumentFilter.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SetSchemaTypeToObjectDocumentFilter.cs
index 2764f868e6..b7902f98e7 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SetSchemaTypeToObjectDocumentFilter.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SetSchemaTypeToObjectDocumentFilter.cs
@@ -1,5 +1,5 @@
 using JetBrains.Annotations;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle;
@@ -11,12 +11,15 @@ internal sealed class SetSchemaTypeToObjectDocumentFilter : IDocumentFilter
 
     public void Apply(OpenApiDocument document, DocumentFilterContext context)
     {
-        foreach (OpenApiSchema schema in document.Components.Schemas.Values)
+        if (document.Components?.Schemas != null)
         {
-            if (schema.Extensions.ContainsKey(RequiresRootObjectTypeKey))
+            foreach (OpenApiSchema schema in document.Components.Schemas.Values.OfType())
             {
-                schema.Type = "object";
-                schema.Extensions.Remove(RequiresRootObjectTypeKey);
+                if (schema.Extensions != null && schema.Extensions.ContainsKey(RequiresRootObjectTypeKey))
+                {
+                    schema.Type = JsonSchemaType.Object;
+                    schema.Extensions.Remove(RequiresRootObjectTypeKey);
+                }
             }
         }
     }
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/DocumentationOpenApiOperationFilter.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/DocumentationOpenApiOperationFilter.cs
index caeb40e96b..54e36cdb08 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/DocumentationOpenApiOperationFilter.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/DocumentationOpenApiOperationFilter.cs
@@ -9,10 +9,11 @@
 using JsonApiDotNetCore.Resources.Annotations;
 using Microsoft.AspNetCore.Mvc.ApiExplorer;
 using Microsoft.Net.Http.Headers;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
+#pragma warning disable AV1568 // Parameter value should not be overwritten in method body
+
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SwaggerComponents;
 
 [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
@@ -76,11 +77,11 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)
 
         bool hasHeadVerb = context.ApiDescription.HttpMethod == "HEAD";
 
-        if (hasHeadVerb)
+        if (hasHeadVerb && operation.Responses?.Values != null)
         {
-            foreach (OpenApiResponse response in operation.Responses.Values)
+            foreach (IOpenApiResponse response in operation.Responses.Values)
             {
-                response.Content.Clear();
+                response.Content?.Clear();
             }
         }
 
@@ -171,7 +172,7 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)
 
     private static void ApplyGetPrimary(OpenApiOperation operation, ResourceType resourceType, bool hasHeadVerb)
     {
-        if (operation.Parameters.Count == 0)
+        if (operation.Parameters == null || operation.Parameters.Count == 0)
         {
             if (hasHeadVerb)
             {
@@ -201,7 +202,7 @@ private static void ApplyGetPrimary(OpenApiOperation operation, ResourceType res
         }
         else if (operation.Parameters.Count == 1)
         {
-            string singularName = resourceType.PublicName.Singularize();
+            string? singularName = resourceType.PublicName.Singularize();
 
             if (hasHeadVerb)
             {
@@ -232,7 +233,7 @@ private static void ApplyGetPrimary(OpenApiOperation operation, ResourceType res
 
     private void ApplyPostResource(OpenApiOperation operation, ResourceType resourceType)
     {
-        string singularName = resourceType.PublicName.Singularize();
+        string? singularName = resourceType.PublicName.Singularize();
 
         SetOperationSummary(operation, $"Creates a new {singularName}.");
         AddQueryStringParameters(operation, false);
@@ -262,10 +263,10 @@ private void ApplyPostResource(OpenApiOperation operation, ResourceType resource
 
     private void ApplyPatchResource(OpenApiOperation operation, ResourceType resourceType)
     {
-        string singularName = resourceType.PublicName.Singularize();
+        string? singularName = resourceType.PublicName.Singularize();
 
         SetOperationSummary(operation, $"Updates an existing {singularName}.");
-        SetParameterDescription(operation.Parameters[0], $"The identifier of the {singularName} to update.");
+        SetParameterDescription(operation.Parameters![0], $"The identifier of the {singularName} to update.");
         AddQueryStringParameters(operation, false);
 
         SetRequestBodyDescription(operation.RequestBody,
@@ -285,18 +286,18 @@ private void ApplyPatchResource(OpenApiOperation operation, ResourceType resourc
 
     private void ApplyDeleteResource(OpenApiOperation operation, ResourceType resourceType)
     {
-        string singularName = resourceType.PublicName.Singularize();
+        string? singularName = resourceType.PublicName.Singularize();
 
         SetOperationSummary(operation, $"Deletes an existing {singularName} by its identifier.");
-        SetParameterDescription(operation.Parameters[0], $"The identifier of the {singularName} to delete.");
+        SetParameterDescription(operation.Parameters![0], $"The identifier of the {singularName} to delete.");
         SetResponseDescription(operation.Responses, HttpStatusCode.NoContent, $"The {singularName} was successfully deleted.");
         SetResponseDescription(operation.Responses, HttpStatusCode.NotFound, $"The {singularName} does not exist.");
     }
 
     private static void ApplyGetSecondary(OpenApiOperation operation, RelationshipAttribute relationship, bool hasHeadVerb)
     {
-        string singularLeftName = relationship.LeftType.PublicName.Singularize();
-        string rightName = relationship is HasOneAttribute ? relationship.RightType.PublicName.Singularize() : relationship.RightType.PublicName;
+        string? singularLeftName = relationship.LeftType.PublicName.Singularize();
+        string? rightName = relationship is HasOneAttribute ? relationship.RightType.PublicName.Singularize() : relationship.RightType.PublicName;
 
         if (hasHeadVerb)
         {
@@ -326,7 +327,7 @@ relationship is HasOneAttribute
             SetResponseHeaderETag(operation.Responses, HttpStatusCode.NotModified);
         }
 
-        SetParameterDescription(operation.Parameters[0], $"The identifier of the {singularLeftName} whose related {rightName} to retrieve.");
+        SetParameterDescription(operation.Parameters![0], $"The identifier of the {singularLeftName} whose related {rightName} to retrieve.");
         AddQueryStringParameters(operation, false);
         AddRequestHeaderIfNoneMatch(operation);
         SetResponseDescription(operation.Responses, HttpStatusCode.BadRequest, TextQueryStringBad);
@@ -335,8 +336,8 @@ relationship is HasOneAttribute
 
     private static void ApplyGetRelationship(OpenApiOperation operation, RelationshipAttribute relationship, bool hasHeadVerb)
     {
-        string singularLeftName = relationship.LeftType.PublicName.Singularize();
-        string singularRightName = relationship.RightType.PublicName.Singularize();
+        string? singularLeftName = relationship.LeftType.PublicName.Singularize();
+        string? singularRightName = relationship.RightType.PublicName.Singularize();
         string ident = relationship is HasOneAttribute ? "identity" : "identities";
 
         if (hasHeadVerb)
@@ -368,7 +369,7 @@ relationship is HasOneAttribute
             SetResponseHeaderETag(operation.Responses, HttpStatusCode.NotModified);
         }
 
-        SetParameterDescription(operation.Parameters[0], $"The identifier of the {singularLeftName} whose related {singularRightName} {ident} to retrieve.");
+        SetParameterDescription(operation.Parameters![0], $"The identifier of the {singularLeftName} whose related {singularRightName} {ident} to retrieve.");
         AddQueryStringParameters(operation, true);
         AddRequestHeaderIfNoneMatch(operation);
         SetResponseDescription(operation.Responses, HttpStatusCode.BadRequest, TextQueryStringBad);
@@ -377,11 +378,11 @@ relationship is HasOneAttribute
 
     private void ApplyPostRelationship(OpenApiOperation operation, RelationshipAttribute relationship)
     {
-        string singularLeftName = relationship.LeftType.PublicName.Singularize();
+        string? singularLeftName = relationship.LeftType.PublicName.Singularize();
         string rightName = relationship.RightType.PublicName;
 
         SetOperationSummary(operation, $"Adds existing {rightName} to the {relationship} relationship of an individual {singularLeftName}.");
-        SetParameterDescription(operation.Parameters[0], $"The identifier of the {singularLeftName} to add {rightName} to.");
+        SetParameterDescription(operation.Parameters![0], $"The identifier of the {singularLeftName} to add {rightName} to.");
         SetRequestBodyDescription(operation.RequestBody, $"The identities of the {rightName} to add to the {relationship} relationship.");
 
         SetResponseDescription(operation.Responses, HttpStatusCode.NoContent,
@@ -396,8 +397,8 @@ private void ApplyPostRelationship(OpenApiOperation operation, RelationshipAttri
     private void ApplyPatchRelationship(OpenApiOperation operation, RelationshipAttribute relationship)
     {
         bool isOptional = _resourceFieldValidationMetadataProvider.IsNullable(relationship);
-        string singularLeftName = relationship.LeftType.PublicName.Singularize();
-        string rightName = relationship is HasOneAttribute ? relationship.RightType.PublicName.Singularize() : relationship.RightType.PublicName;
+        string? singularLeftName = relationship.LeftType.PublicName.Singularize();
+        string? rightName = relationship is HasOneAttribute ? relationship.RightType.PublicName.Singularize() : relationship.RightType.PublicName;
 
         SetOperationSummary(operation,
             relationship is HasOneAttribute
@@ -406,7 +407,7 @@ relationship is HasOneAttribute
                     : $"Assigns an existing {rightName} to the {relationship} relationship of an individual {singularLeftName}."
                 : $"Assigns existing {rightName} to the {relationship} relationship of an individual {singularLeftName}.");
 
-        SetParameterDescription(operation.Parameters[0],
+        SetParameterDescription(operation.Parameters![0],
             isOptional
                 ? $"The identifier of the {singularLeftName} whose {relationship} relationship to assign or clear."
                 : $"The identifier of the {singularLeftName} whose {relationship} relationship to assign.");
@@ -429,11 +430,11 @@ relationship is HasOneAttribute
 
     private void ApplyDeleteRelationship(OpenApiOperation operation, RelationshipAttribute relationship)
     {
-        string singularLeftName = relationship.LeftType.PublicName.Singularize();
+        string? singularLeftName = relationship.LeftType.PublicName.Singularize();
         string rightName = relationship.RightType.PublicName;
 
         SetOperationSummary(operation, $"Removes existing {rightName} from the {relationship} relationship of an individual {singularLeftName}.");
-        SetParameterDescription(operation.Parameters[0], $"The identifier of the {singularLeftName} to remove {rightName} from.");
+        SetParameterDescription(operation.Parameters![0], $"The identifier of the {singularLeftName} to remove {rightName} from.");
         SetRequestBodyDescription(operation.RequestBody, $"The identities of the {rightName} to remove from the {relationship} relationship.");
 
         SetResponseDescription(operation.Responses, HttpStatusCode.NoContent,
@@ -463,64 +464,76 @@ private static void SetOperationRemarks(OpenApiOperation operation, string descr
         operation.Description = XmlCommentsTextHelper.Humanize(description);
     }
 
-    private static void SetParameterDescription(OpenApiParameter parameter, string description)
+    private static void SetParameterDescription(IOpenApiParameter parameter, string description)
     {
         parameter.Description = XmlCommentsTextHelper.Humanize(description);
     }
 
-    private static void SetRequestBodyDescription(OpenApiRequestBody requestBody, string description)
+    private static void SetRequestBodyDescription(IOpenApiRequestBody? requestBody, string description)
     {
+        requestBody ??= new OpenApiRequestBody();
         requestBody.Description = XmlCommentsTextHelper.Humanize(description);
     }
 
-    private static void SetResponseDescription(OpenApiResponses responses, HttpStatusCode statusCode, string description)
+    private static void SetResponseDescription(OpenApiResponses? responses, HttpStatusCode statusCode, string description)
     {
+        responses ??= new OpenApiResponses();
+
         OpenApiResponse response = GetOrAddResponse(responses, statusCode);
         response.Description = XmlCommentsTextHelper.Humanize(description);
     }
 
-    private static void SetResponseHeaderETag(OpenApiResponses responses, HttpStatusCode statusCode)
+    private static void SetResponseHeaderETag(OpenApiResponses? responses, HttpStatusCode statusCode)
     {
+        responses ??= new OpenApiResponses();
         OpenApiResponse response = GetOrAddResponse(responses, statusCode);
 
+        response.Headers ??= new SortedDictionary();
+
         response.Headers[HeaderNames.ETag] = new OpenApiHeader
         {
             Description = "A fingerprint of the HTTP response, which can be used in an If-None-Match header to only fetch changes.",
             Required = true,
             Schema = new OpenApiSchema
             {
-                Type = "string"
+                Type = JsonSchemaType.String
             }
         };
     }
 
-    private static void SetResponseHeaderContentLength(OpenApiResponses responses, HttpStatusCode statusCode)
+    private static void SetResponseHeaderContentLength(OpenApiResponses? responses, HttpStatusCode statusCode)
     {
+        responses ??= new OpenApiResponses();
         OpenApiResponse response = GetOrAddResponse(responses, statusCode);
 
+        response.Headers ??= new SortedDictionary();
+
         response.Headers[HeaderNames.ContentLength] = new OpenApiHeader
         {
             Description = "Size of the HTTP response body, in bytes.",
             Required = true,
             Schema = new OpenApiSchema
             {
-                Type = "integer",
+                Type = JsonSchemaType.Integer,
                 Format = "int64"
             }
         };
     }
 
-    private static void SetResponseHeaderLocation(OpenApiResponses responses, HttpStatusCode statusCode, string resourceName)
+    private static void SetResponseHeaderLocation(OpenApiResponses? responses, HttpStatusCode statusCode, string resourceName)
     {
+        responses ??= new OpenApiResponses();
         OpenApiResponse response = GetOrAddResponse(responses, statusCode);
 
+        response.Headers ??= new SortedDictionary();
+
         response.Headers[HeaderNames.Location] = new OpenApiHeader
         {
             Description = $"The URL at which the newly created {resourceName} can be retrieved.",
             Required = true,
             Schema = new OpenApiSchema
             {
-                Type = "string",
+                Type = JsonSchemaType.String,
                 Format = "uri"
             }
         };
@@ -530,13 +543,15 @@ private static OpenApiResponse GetOrAddResponse(OpenApiResponses responses, Http
     {
         string responseCode = ((int)statusCode).ToString();
 
-        if (!responses.TryGetValue(responseCode, out OpenApiResponse? response))
+        if (!responses.TryGetValue(responseCode, out IOpenApiResponse? response) || response is not OpenApiResponse)
         {
             response = new OpenApiResponse();
             responses.Add(responseCode, response);
         }
 
-        return response;
+        var concreteResponse = (OpenApiResponse)response;
+        concreteResponse.Headers ??= new Dictionary();
+        return concreteResponse;
     }
 
     private static void AddQueryStringParameters(OpenApiOperation operation, bool isRelationshipEndpoint)
@@ -551,20 +566,21 @@ private static void AddQueryStringParameters(OpenApiOperation operation, bool is
         // - This makes NSwag produce a C# client with method signature: GetAsync(IDictionary? query)
         //     when combined with true in the project file.
 
+        operation.Parameters ??= [];
+
         operation.Parameters.Add(new OpenApiParameter
         {
             In = ParameterLocation.Query,
             Name = "query",
             Schema = new OpenApiSchema
             {
-                Type = "object",
+                Type = JsonSchemaType.Object,
                 AdditionalProperties = new OpenApiSchema
                 {
-                    Type = "string",
-                    Nullable = true
+                    Type = JsonSchemaType.String | JsonSchemaType.Null
                 },
                 // Prevent SwaggerUI from producing sample, which fails when used because unknown query string parameters are blocked by default.
-                Example = new OpenApiString(string.Empty)
+                Example = string.Empty
             },
             Description = isRelationshipEndpoint ? RelationshipQueryStringParameters : ResourceQueryStringParameters
         });
@@ -572,6 +588,8 @@ private static void AddQueryStringParameters(OpenApiOperation operation, bool is
 
     private static void AddRequestHeaderIfNoneMatch(OpenApiOperation operation)
     {
+        operation.Parameters ??= [];
+
         operation.Parameters.Add(new OpenApiParameter
         {
             In = ParameterLocation.Header,
@@ -579,7 +597,7 @@ private static void AddRequestHeaderIfNoneMatch(OpenApiOperation operation)
             Description = "A list of ETags, resulting in HTTP status 304 without a body, if one of them matches the current fingerprint.",
             Schema = new OpenApiSchema
             {
-                Type = "string"
+                Type = JsonSchemaType.String
             }
         });
     }
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/EndpointOrderingFilter.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/EndpointOrderingFilter.cs
index 047ba4355a..c0dd869906 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/EndpointOrderingFilter.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/EndpointOrderingFilter.cs
@@ -1,6 +1,6 @@
 using System.Text.RegularExpressions;
 using JetBrains.Annotations;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
 using Swashbuckle.AspNetCore.SwaggerGen;
 
 namespace JsonApiDotNetCore.OpenApi.Swashbuckle.SwaggerComponents;
@@ -13,28 +13,43 @@ public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
         ArgumentNullException.ThrowIfNull(swaggerDoc);
         ArgumentNullException.ThrowIfNull(context);
 
-        KeyValuePair[] endpointsInOrder = swaggerDoc.Paths.OrderBy(GetPrimaryResourcePublicName)
+        KeyValuePair[] endpointsInOrder = swaggerDoc.Paths.OrderBy(GetPrimaryResourcePublicName)
             .ThenBy(GetRelationshipName).ThenBy(IsSecondaryEndpoint).ToArray();
 
-        swaggerDoc.Paths.Clear();
+        swaggerDoc.Paths = new OpenApiPaths();
 
-        foreach ((string url, OpenApiPathItem path) in endpointsInOrder)
+        foreach ((string url, IOpenApiPathItem path) in endpointsInOrder)
         {
             swaggerDoc.Paths.Add(url, path);
         }
     }
 
-    private static string GetPrimaryResourcePublicName(KeyValuePair entry)
+    private static string GetPrimaryResourcePublicName(KeyValuePair entry)
     {
-        return entry.Value.Operations.First().Value.Tags.First().Name;
+        if (entry.Value.Operations is { Count: > 0 })
+        {
+            ISet? references = entry.Value.Operations.First().Value.Tags;
+
+            if (references is { Count: > 0 })
+            {
+                OpenApiTagReference openApiTagReference = references.First();
+
+                if (openApiTagReference.Name != null)
+                {
+                    return openApiTagReference.Name;
+                }
+            }
+        }
+
+        throw new InvalidOperationException($"Failed to find tag value for endpoint '{entry.Key}'.");
     }
 
-    private static bool IsSecondaryEndpoint(KeyValuePair entry)
+    private static bool IsSecondaryEndpoint(KeyValuePair entry)
     {
         return entry.Key.Contains("/relationships");
     }
 
-    private static string GetRelationshipName(KeyValuePair entry)
+    private static string GetRelationshipName(KeyValuePair entry)
     {
         Match match = RelationshipNameInUrlRegex().Match(entry.Key);
 
diff --git a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/JsonApiDataContractResolver.cs b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/JsonApiDataContractResolver.cs
index dcc652c696..ba1cc86d99 100644
--- a/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/JsonApiDataContractResolver.cs
+++ b/src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/JsonApiDataContractResolver.cs
@@ -33,7 +33,7 @@ public DataContract GetDataContractForType(Type type)
             return DataContract.ForDynamic(typeof(object));
         }
 
-        DataContract dataContract = _dataContractResolver.GetDataContractForType(type);
+        DataContract? dataContract = _dataContractResolver.GetDataContractForType(type);
 
         IList? replacementProperties = null;
 
@@ -61,7 +61,7 @@ private List GetDataPropertiesThatExistInResourceClrType(Type reso
         ResourceType resourceType = _resourceGraph.GetResourceType(resourceClrType);
         List dataProperties = [];
 
-        foreach (DataProperty property in dataContract.ObjectProperties)
+        foreach (DataProperty? property in dataContract.ObjectProperties)
         {
             if (property.MemberInfo.Name == nameof(Identifiable