diff --git a/src/Simplic.OxS.Server/Extensions/GraphQLExtension.cs b/src/Simplic.OxS.Server/Extensions/GraphQLExtension.cs
index 705f6f1..6b2155d 100644
--- a/src/Simplic.OxS.Server/Extensions/GraphQLExtension.cs
+++ b/src/Simplic.OxS.Server/Extensions/GraphQLExtension.cs
@@ -1,5 +1,6 @@
using HotChocolate.Execution.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Simplic.OxS.Server.GraphQL;
using Simplic.OxS.Server.Middleware;
namespace Simplic.OxS.Server.Extensions
@@ -7,11 +8,21 @@ namespace Simplic.OxS.Server.Extensions
public static class GraphQLExtension
{
///
- /// Enable the use of GraphQL within the simplic eco system
+ /// Enable the use of GraphQL within the simplic eco system.
///
- ///
- ///
- public static IServiceCollection UseGraphQL(this IServiceCollection services, Action builder = null) where TQuery : class
+ /// DI service collection.
+ /// Optional builder hook for service-specific extensions.
+ ///
+ /// When true (default), every output field on user-defined object types is
+ /// made nullable in the generated schema. This prevents NonNull spec
+ /// violations when a resolver returns null for a property that wasn't
+ /// stored on legacy documents. Set to false for strict, spec-conformant
+ /// non-null behavior (clients then must handle the propagated null).
+ ///
+ public static IServiceCollection UseGraphQL(
+ this IServiceCollection services,
+ Action builder = null,
+ bool tolerateMissingFieldValues = true) where TQuery : class
{
var req = services.AddGraphQLServer().ModifyOptions(o =>
{
@@ -22,6 +33,9 @@ public static IServiceCollection UseGraphQL(this IServiceCollection serv
.AddAuthorization()
.AddQueryType();
+ if (tolerateMissingFieldValues)
+ req.TryAddTypeInterceptor();
+
// Set TimeSpan representation to d.hh:mm:ss
req.AddType(new TimeSpanType(TimeSpanFormat.DotNet));
diff --git a/src/Simplic.OxS.Server/GraphQL/MakeFieldsNullableTypeInterceptor.cs b/src/Simplic.OxS.Server/GraphQL/MakeFieldsNullableTypeInterceptor.cs
new file mode 100644
index 0000000..17aaa94
--- /dev/null
+++ b/src/Simplic.OxS.Server/GraphQL/MakeFieldsNullableTypeInterceptor.cs
@@ -0,0 +1,56 @@
+using HotChocolate.Configuration;
+using HotChocolate.Types.Descriptors;
+using HotChocolate.Types.Descriptors.Configurations;
+
+namespace Simplic.OxS.Server.GraphQL
+{
+ ///
+ /// HotChocolate type interceptor that rewrites every output field of every
+ /// user-defined object type so its outermost type becomes nullable.
+ ///
+ /// Purpose: tolerate items that are missing values for fields the schema
+ /// would otherwise mark as NonNull. Without this interceptor, a
+ /// resolver returning null for a !-field causes the parent
+ /// selection-set to be replaced by null (per GraphQL spec).
+ ///
+ ///
+ /// HotChocolate built-in types (introspection, paging connections, etc.)
+ /// are skipped because clients depend on their non-null guarantees.
+ ///
+ ///
+ internal sealed class MakeFieldsNullableTypeInterceptor : TypeInterceptor
+ {
+ public override void OnBeforeCompleteName(
+ ITypeCompletionContext completionContext,
+ TypeSystemConfiguration configuration)
+ {
+ if (completionContext.IsIntrospectionType)
+ return;
+
+ if (configuration is not ObjectTypeConfiguration objectConfig)
+ return;
+
+ // Skip HotChocolate's own types (Connection, Edge, PageInfo, ...).
+ var runtimeType = objectConfig.RuntimeType;
+ if (runtimeType?.Namespace is { } ns &&
+ ns.StartsWith("HotChocolate", System.StringComparison.Ordinal))
+ {
+ return;
+ }
+
+ foreach (var field in objectConfig.Fields)
+ {
+ if (field.IsIntrospectionField)
+ continue;
+
+ if (field.Type is not ExtendedTypeReference extRef)
+ continue;
+
+ var nullableType = completionContext.TypeInspector
+ .ChangeNullability(extRef.Type, true);
+
+ field.Type = extRef.WithType(nullableType);
+ }
+ }
+ }
+}