From a43bb57619e9ead7ae154a3bc152b8e4ea756185 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Tue, 9 Aug 2022 20:35:44 +0200 Subject: [PATCH] Simplify scoped resolver compiler extensions. (#5286) --- .../Resolvers/DefaultResolverCompiler.cs | 26 ++++---- .../src/Types/Resolvers/IResolverCompiler.cs | 6 +- .../Definitions/InterfaceFieldDefinition.cs | 59 +++++++++++++++++++ .../Definitions/ObjectFieldDefinition.cs | 41 ++++++++++++- .../Types/Descriptors/DescriptorBase~1.cs | 13 +--- .../Descriptors/InterfaceFieldDescriptor.cs | 3 +- .../Descriptors/ObjectFieldDescriptor.cs | 30 +++++----- .../Types/Helpers/FieldDescriptorUtilities.cs | 17 +++--- .../Core/src/Types/Types/ObjectField.cs | 6 +- .../Types/Relay/NodeResolverCompilerHelper.cs | 2 +- .../Resolvers/ResolverCompilerTests.cs | 57 ++++++++++++++++++ ...sts.ScopedExpressionBuilderSchemaTest.snap | 13 ++++ ...ilerTests.ScopedExpressionBuilderTest.snap | 5 ++ 13 files changed, 223 insertions(+), 55 deletions(-) create mode 100644 src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderSchemaTest.snap create mode 100644 src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderTest.snap diff --git a/src/HotChocolate/Core/src/Types/Resolvers/DefaultResolverCompiler.cs b/src/HotChocolate/Core/src/Types/Resolvers/DefaultResolverCompiler.cs index c7cc1a237d3..b7571b0a9d1 100644 --- a/src/HotChocolate/Core/src/Types/Resolvers/DefaultResolverCompiler.cs +++ b/src/HotChocolate/Core/src/Types/Resolvers/DefaultResolverCompiler.cs @@ -22,7 +22,7 @@ namespace HotChocolate.Resolvers; /// internal sealed class DefaultResolverCompiler : IResolverCompiler { - private static readonly IParameterExpressionBuilder[] _empty = + private static readonly IReadOnlyList _empty = Array.Empty(); private static readonly ParameterExpression _context = Parameter(typeof(IResolverContext), "context"); @@ -137,7 +137,7 @@ internal sealed class DefaultResolverCompiler : IResolverCompiler public FieldResolverDelegates CompileResolve( Expression> propertyOrMethod, Type? sourceType = null, - IParameterExpressionBuilder[]? parameterExpressionBuilders = null) + IReadOnlyList? parameterExpressionBuilders = null) { if (propertyOrMethod is null) { @@ -182,7 +182,7 @@ internal sealed class DefaultResolverCompiler : IResolverCompiler MemberInfo member, Type? sourceType = null, Type? resolverType = null, - IParameterExpressionBuilder[]? parameterExpressionBuilders = null) + IReadOnlyList? parameterExpressionBuilders = null) { if (member is null) { @@ -249,7 +249,7 @@ internal sealed class DefaultResolverCompiler : IResolverCompiler /// public IEnumerable GetArgumentParameters( ParameterInfo[] parameters, - IParameterExpressionBuilder[]? parameterExpressionBuilders = null) + IReadOnlyList? parameterExpressionBuilders = null) { if (parameters is null) { @@ -295,7 +295,7 @@ internal sealed class DefaultResolverCompiler : IResolverCompiler private FieldResolverDelegate CompileStaticResolver( MethodInfo method, - IParameterExpressionBuilder[] fieldParameterExpressionBuilders) + IReadOnlyList fieldParameterExpressionBuilders) { var parameters = CreateParameters( _context, @@ -310,7 +310,7 @@ internal sealed class DefaultResolverCompiler : IResolverCompiler MemberInfo member, Type source, Type resolverType, - IParameterExpressionBuilder[] fieldParameterExpressionBuilders) + IReadOnlyList fieldParameterExpressionBuilders) { if (member is PropertyInfo property) { @@ -341,7 +341,7 @@ internal sealed class DefaultResolverCompiler : IResolverCompiler MemberInfo member, Type source, Type resolver, - IParameterExpressionBuilder[] fieldParameterExpressionBuilders) + IReadOnlyList fieldParameterExpressionBuilders) { if (member is PropertyInfo property && IsPureResolverResult(property.PropertyType)) { @@ -384,7 +384,7 @@ internal sealed class DefaultResolverCompiler : IResolverCompiler private bool IsPureResolver( MethodInfo method, ParameterInfo[] parameters, - IParameterExpressionBuilder[] fieldParameterExpressionBuilders) + IReadOnlyList fieldParameterExpressionBuilders) { if (!IsPureResolverResult(method.ReturnType)) { @@ -447,7 +447,7 @@ private static bool IsPureResolverResult(Type resultType) private Expression[] CreateParameters( ParameterExpression context, ParameterInfo[] parameters, - IParameterExpressionBuilder[] fieldParameterExpressionBuilders) + IReadOnlyList fieldParameterExpressionBuilders) { var parameterResolvers = new Expression[parameters.Length]; @@ -466,15 +466,15 @@ private static bool IsPureResolverResult(Type resultType) private IParameterExpressionBuilder GetParameterExpressionBuilder( ParameterInfo parameter, - IParameterExpressionBuilder[] fieldParameterExpressionBuilders) + IReadOnlyList fieldParameterExpressionBuilders) { - if (fieldParameterExpressionBuilders.Length == 0 && + if (fieldParameterExpressionBuilders.Count == 0 && _cache.TryGetValue(parameter, out var cached)) { return cached; } - if (fieldParameterExpressionBuilders.Length > 0) + if (fieldParameterExpressionBuilders.Count > 0) { foreach (var builder in fieldParameterExpressionBuilders) { @@ -503,7 +503,7 @@ private static bool IsPureResolverResult(Type resultType) } } - if (fieldParameterExpressionBuilders.Length > 0) + if (fieldParameterExpressionBuilders.Count > 0) { foreach (var builder in fieldParameterExpressionBuilders) { diff --git a/src/HotChocolate/Core/src/Types/Resolvers/IResolverCompiler.cs b/src/HotChocolate/Core/src/Types/Resolvers/IResolverCompiler.cs index cc7b5849309..e60cc5f10ef 100644 --- a/src/HotChocolate/Core/src/Types/Resolvers/IResolverCompiler.cs +++ b/src/HotChocolate/Core/src/Types/Resolvers/IResolverCompiler.cs @@ -35,7 +35,7 @@ public interface IResolverCompiler : IDisposable FieldResolverDelegates CompileResolve( Expression> propertyOrMethod, Type? sourceType = null, - IParameterExpressionBuilder[]? parameterExpressionBuilders = null); + IReadOnlyList? parameterExpressionBuilders = null); /// /// Compiles a resolver from a member selector. @@ -79,7 +79,7 @@ public interface IResolverCompiler : IDisposable MemberInfo member, Type? sourceType = null, Type? resolverType = null, - IParameterExpressionBuilder[]? parameterExpressionBuilders = null); + IReadOnlyList? parameterExpressionBuilders = null); /// /// Compiles a subscribe resolver from a member. @@ -116,7 +116,7 @@ public interface IResolverCompiler : IDisposable /// IEnumerable GetArgumentParameters( ParameterInfo[] parameters, - IParameterExpressionBuilder[]? parameterExpressionBuilders = null); + IReadOnlyList? parameterExpressionBuilders = null); /// /// Applies filed configuration dependencies for the specified parameters. diff --git a/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/InterfaceFieldDefinition.cs b/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/InterfaceFieldDefinition.cs index 19cdef791f5..719884bc667 100644 --- a/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/InterfaceFieldDefinition.cs +++ b/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/InterfaceFieldDefinition.cs @@ -1,4 +1,7 @@ +using System; +using System.Collections.Generic; using System.Reflection; +using HotChocolate.Internal; using HotChocolate.Utilities; #nullable enable @@ -11,6 +14,8 @@ namespace HotChocolate.Types.Descriptors.Definitions; /// public class InterfaceFieldDefinition : OutputFieldDefinitionBase { + private List? _expressionBuilders; + /// /// Initializes a new instance of . /// @@ -33,4 +38,58 @@ public class InterfaceFieldDefinition : OutputFieldDefinitionBase /// Gets the interface member to which this field is bound to. /// public MemberInfo? Member { get; set; } + + /// + /// A list of parameter expression builders that shall be applied when compiling + /// the resolver or when arguments are inferred from a method. + /// + public IList ParameterExpressionBuilders + { + get + { + return _expressionBuilders ??= new List(); + } + } + + /// + /// A list of parameter expression builders that shall be applied when compiling + /// the resolver or when arguments are inferred from a method. + /// + internal IReadOnlyList GetParameterExpressionBuilders() + { + if (_expressionBuilders is null) + { + return Array.Empty(); + } + + return _expressionBuilders; + } + + internal void CopyTo(InterfaceFieldDefinition target) + { + base.CopyTo(target); + + if (_expressionBuilders is { Count: > 0 }) + { + target._expressionBuilders = new(_expressionBuilders); + } + + target.Member = Member; + } + + internal void MergeInto(InterfaceFieldDefinition target) + { + base.MergeInto(target); + + if (_expressionBuilders is { Count: > 0 }) + { + target._expressionBuilders ??= new List(); + target._expressionBuilders.AddRange(_expressionBuilders); + } + + if (Member is not null) + { + target.Member = Member; + } + } } diff --git a/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/ObjectFieldDefinition.cs b/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/ObjectFieldDefinition.cs index 6f0077d91af..9c4bf420adb 100644 --- a/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/ObjectFieldDefinition.cs +++ b/src/HotChocolate/Core/src/Types/Types/Descriptors/Definitions/ObjectFieldDefinition.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; +using HotChocolate.Internal; using HotChocolate.Resolvers; using HotChocolate.Utilities; @@ -18,6 +19,7 @@ public class ObjectFieldDefinition : OutputFieldDefinitionBase { private List? _middlewareDefinitions; private List? _resultConverters; + private List? _expressionBuilders; private List? _customSettings; private bool _middlewareDefinitionsCleaned; private bool _resultConvertersCleaned; @@ -137,7 +139,19 @@ public IList ResultConverters } /// - /// A list of custom settings objects that can be user in the type interceptors. + /// A list of parameter expression builders that shall be applied when compiling + /// the resolver or when arguments are inferred from a method. + /// + public IList ParameterExpressionBuilders + { + get + { + return _expressionBuilders ??= new List(); + } + } + + /// + /// A list of custom settings objects that can be used in the type interceptors. /// Custom settings are not copied to the actual type system object. /// public IList CustomSettings @@ -231,6 +245,20 @@ internal IReadOnlyList GetResultConverters() return _resultConverters; } + /// + /// A list of parameter expression builders that shall be applied when compiling + /// the resolver or when arguments are inferred from a method. + /// + internal IReadOnlyList GetParameterExpressionBuilders() + { + if (_expressionBuilders is null) + { + return Array.Empty(); + } + + return _expressionBuilders; + } + /// /// A list of custom settings objects that can be user in the type interceptors. /// Custom settings are not copied to the actual type system object. @@ -264,6 +292,11 @@ internal void CopyTo(ObjectFieldDefinition target) _resultConvertersCleaned = false; } + if (_expressionBuilders is { Count: > 0 }) + { + target._expressionBuilders = new(_expressionBuilders); + } + if (_customSettings is { Count: > 0 }) { target._customSettings = new(_customSettings); @@ -302,6 +335,12 @@ internal void MergeInto(ObjectFieldDefinition target) _resultConvertersCleaned = false; } + if (_expressionBuilders is { Count: > 0 }) + { + target._expressionBuilders ??= new List(); + target._expressionBuilders.AddRange(_expressionBuilders); + } + if (_customSettings is { Count: > 0 }) { target._customSettings ??= new List(); diff --git a/src/HotChocolate/Core/src/Types/Types/Descriptors/DescriptorBase~1.cs b/src/HotChocolate/Core/src/Types/Types/Descriptors/DescriptorBase~1.cs index 24feca6f4fb..eb61edc3a9b 100644 --- a/src/HotChocolate/Core/src/Types/Types/Descriptors/DescriptorBase~1.cs +++ b/src/HotChocolate/Core/src/Types/Types/Descriptors/DescriptorBase~1.cs @@ -36,9 +36,6 @@ public T CreateDefinition() if (Definition.HasConfigurations) { var i = 0; - var buffered = 0; - var length = Definition.Configurations.Count; - var rented = ArrayPool.Shared.Rent(length); var configurations = Definition.Configurations; do @@ -46,21 +43,13 @@ public T CreateDefinition() if (configurations[i] is { On: ApplyConfigurationOn.Create } config) { configurations.RemoveAt(i); - rented[buffered++] = (CreateConfiguration)config; + ((CreateConfiguration)config).Configure(Context); } else { i++; } } while (i < configurations.Count); - - for (i = 0; i < buffered; i++) - { - rented[i].Configure(Context); - } - - rented.AsSpan().Slice(0, length).Clear(); - ArrayPool.Shared.Return(rented, true); } return Definition; diff --git a/src/HotChocolate/Core/src/Types/Types/Descriptors/InterfaceFieldDescriptor.cs b/src/HotChocolate/Core/src/Types/Types/Descriptors/InterfaceFieldDescriptor.cs index 621b3a45441..9fff030fd84 100644 --- a/src/HotChocolate/Core/src/Types/Types/Descriptors/InterfaceFieldDescriptor.cs +++ b/src/HotChocolate/Core/src/Types/Types/Descriptors/InterfaceFieldDescriptor.cs @@ -74,7 +74,8 @@ private void CompleteArguments(InterfaceFieldDefinition definition) FieldDescriptorUtilities.DiscoverArguments( Context, definition.Arguments, - definition.Member); + definition.Member, + definition.GetParameterExpressionBuilders()); _argumentsInitialized = true; } } diff --git a/src/HotChocolate/Core/src/Types/Types/Descriptors/ObjectFieldDescriptor.cs b/src/HotChocolate/Core/src/Types/Types/Descriptors/ObjectFieldDescriptor.cs index 972340b34d9..0fe4c1b0217 100644 --- a/src/HotChocolate/Core/src/Types/Types/Descriptors/ObjectFieldDescriptor.cs +++ b/src/HotChocolate/Core/src/Types/Types/Descriptors/ObjectFieldDescriptor.cs @@ -33,8 +33,7 @@ public class ObjectFieldDescriptor { Definition.Name = fieldName; Definition.ResultType = typeof(object); - Definition.IsParallelExecutable = - context.Options.DefaultResolverStrategy is Parallel; + Definition.IsParallelExecutable = context.Options.DefaultResolverStrategy is Parallel; } /// @@ -165,7 +164,8 @@ private void CompleteArguments(ObjectFieldDefinition definition) FieldDescriptorUtilities.DiscoverArguments( Context, definition.Arguments, - definition.Member); + definition.Member, + definition.GetParameterExpressionBuilders()); _argumentsInitialized = true; } @@ -194,8 +194,8 @@ public new IObjectFieldDescriptor Description(string? value) /// [Obsolete("Use `Deprecated`.")] - public IObjectFieldDescriptor DeprecationReason(string? reason) => - Deprecated(reason); + public IObjectFieldDescriptor DeprecationReason(string? reason) + => Deprecated(reason); /// public new IObjectFieldDescriptor Deprecated(string? reason) @@ -265,8 +265,8 @@ public new IObjectFieldDescriptor Ignore(bool ignore = true) } /// - public IObjectFieldDescriptor Resolver(FieldResolverDelegate fieldResolver) => - Resolve(fieldResolver); + public IObjectFieldDescriptor Resolver(FieldResolverDelegate fieldResolver) + => Resolve(fieldResolver); /// public IObjectFieldDescriptor Resolver( @@ -412,8 +412,8 @@ public new IObjectFieldDescriptor Directive() /// An instance of public static ObjectFieldDescriptor New( IDescriptorContext context, - string fieldName) => - new(context, fieldName); + string fieldName) + => new(context, fieldName); /// /// Creates a new instance of @@ -427,8 +427,8 @@ public new IObjectFieldDescriptor Directive() IDescriptorContext context, MemberInfo member, Type sourceType, - Type? resolverType = null) => - new(context, member, sourceType, resolverType); + Type? resolverType = null) + => new(context, member, sourceType, resolverType); /// /// Creates a new instance of @@ -442,8 +442,8 @@ public new IObjectFieldDescriptor Directive() IDescriptorContext context, LambdaExpression expression, Type sourceType, - Type? resolverType = null) => - new(context, expression, sourceType, resolverType); + Type? resolverType = null) + => new(context, expression, sourceType, resolverType); /// /// Creates a new instance of @@ -453,6 +453,6 @@ public new IObjectFieldDescriptor Directive() /// public static ObjectFieldDescriptor From( IDescriptorContext context, - ObjectFieldDefinition definition) => - new(context, definition); + ObjectFieldDefinition definition) + => new(context, definition); } diff --git a/src/HotChocolate/Core/src/Types/Types/Helpers/FieldDescriptorUtilities.cs b/src/HotChocolate/Core/src/Types/Types/Helpers/FieldDescriptorUtilities.cs index 955ab8cb229..c07c97e7308 100644 --- a/src/HotChocolate/Core/src/Types/Types/Helpers/FieldDescriptorUtilities.cs +++ b/src/HotChocolate/Core/src/Types/Types/Helpers/FieldDescriptorUtilities.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using System.Threading; +using HotChocolate.Internal; using HotChocolate.Types.Descriptors; using HotChocolate.Types.Descriptors.Definitions; @@ -24,7 +25,7 @@ public static class FieldDescriptorUtilities { foreach (var fieldDefinition in fieldDefinitions) { - if (!fieldDefinition.Ignore && fieldDefinition.Name is not null) + if (!fieldDefinition.Ignore && !string.IsNullOrEmpty(fieldDefinition.Name)) { fields[fieldDefinition.Name] = fieldDefinition; } @@ -79,7 +80,7 @@ public static class FieldDescriptorUtilities { var fieldDefinition = createdFieldDefinition(member); - if (fieldDefinition.Name is not null && + if (!string.IsNullOrEmpty(fieldDefinition.Name) && !handledMembers.Contains(member) && !fields.ContainsKey(fieldDefinition.Name) && (includeIgnoredMembers || !fieldDefinition.Ignore)) @@ -95,7 +96,8 @@ public static class FieldDescriptorUtilities public static void DiscoverArguments( IDescriptorContext context, ICollection arguments, - MemberInfo? member) + MemberInfo? member, + IReadOnlyList? parameterExpressionBuilders) { if (arguments is null) { @@ -110,21 +112,23 @@ public static class FieldDescriptorUtilities { foreach (var argument in arguments) { - if (argument.Name is not null) + if (!string.IsNullOrEmpty(argument.Name)) { processedNames.Add(argument.Name); } } foreach (var parameter in - context.ResolverCompiler.GetArgumentParameters(method.GetParameters())) + context.ResolverCompiler.GetArgumentParameters( + method.GetParameters(), + parameterExpressionBuilders)) { var argumentDefinition = ArgumentDescriptor .New(context, parameter) .CreateDefinition(); - if (argumentDefinition.Name is not null && + if (!string.IsNullOrEmpty(argumentDefinition.Name) && processedNames.Add(argumentDefinition.Name)) { arguments.Add(argumentDefinition); @@ -134,7 +138,6 @@ public static class FieldDescriptorUtilities finally { processedNames.Clear(); - Interlocked.CompareExchange(ref _names, processedNames, null); } } diff --git a/src/HotChocolate/Core/src/Types/Types/ObjectField.cs b/src/HotChocolate/Core/src/Types/Types/ObjectField.cs index 701179cd864..3c2c77cf84d 100644 --- a/src/HotChocolate/Core/src/Types/Types/ObjectField.cs +++ b/src/HotChocolate/Core/src/Types/Types/ObjectField.cs @@ -260,7 +260,8 @@ bool IsPureContext() definition.Member?.ReflectedType ?? definition.Member?.DeclaringType ?? typeof(object), - definition.ResolverType); + definition.ResolverType, + definition.GetParameterExpressionBuilders()); } else if (definition.Member is not null) { @@ -269,7 +270,8 @@ bool IsPureContext() definition.SourceType ?? definition.Member.ReflectedType ?? definition.Member.DeclaringType, - definition.ResolverType); + definition.ResolverType, + definition.GetParameterExpressionBuilders()); } } diff --git a/src/HotChocolate/Core/src/Types/Types/Relay/NodeResolverCompilerHelper.cs b/src/HotChocolate/Core/src/Types/Types/Relay/NodeResolverCompilerHelper.cs index a710f31c2db..f1caca943b2 100644 --- a/src/HotChocolate/Core/src/Types/Types/Relay/NodeResolverCompilerHelper.cs +++ b/src/HotChocolate/Core/src/Types/Types/Relay/NodeResolverCompilerHelper.cs @@ -6,6 +6,6 @@ internal static class NodeResolverCompilerHelper { public static readonly IParameterExpressionBuilder[] ParameterExpressionBuilders = { - NodeIdParameterExpressionBuilder.Instance + NodeIdParameterExpressionBuilder.Instance }; } diff --git a/src/HotChocolate/Core/test/Types.Tests/Resolvers/ResolverCompilerTests.cs b/src/HotChocolate/Core/test/Types.Tests/Resolvers/ResolverCompilerTests.cs index 7937b51f4ef..4cb00c1c496 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Resolvers/ResolverCompilerTests.cs +++ b/src/HotChocolate/Core/test/Types.Tests/Resolvers/ResolverCompilerTests.cs @@ -13,6 +13,7 @@ using HotChocolate.Language; using HotChocolate.Tests; using HotChocolate.Types; +using HotChocolate.Types.Descriptors; using Moq; using Snapshooter.Xunit; using Xunit; @@ -1311,6 +1312,30 @@ public async Task SchemaIntegrationTest() .MatchSnapshotAsync(); } + [Fact] + public async Task ScopedExpressionBuilderTest() + { + // arrange + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.SortFieldsByName = true) + .ExecuteRequestAsync("{ bar }") + .MatchSnapshotAsync(); + } + + [Fact] + public async Task ScopedExpressionBuilderSchemaTest() + { + // arrange + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.SortFieldsByName = true) + .BuildSchemaAsync() + .MatchSnapshotAsync(); + } + public class Resolvers { public Task ObjectTaskResolver() => @@ -1506,4 +1531,36 @@ public bool GetPath(Path path) public class Entity { } public class MyService { } + + public class QueryWithScopedExpressionBuilder + { + [UseSomeState] + public string Bar(SomeState someState) + => someState.Foo; + } + + public class SomeState + { + public string Foo => "Abc"; + } + + public class UseSomeStateAttribute : ObjectFieldDescriptorAttribute + { + public override void OnConfigure( + IDescriptorContext context, + IObjectFieldDescriptor descriptor, + MemberInfo member) + { + descriptor.Use( + n => c => + { + c.SetLocalState("foo", new SomeState()); + return n(c); + }); + + descriptor.Extend().Definition.ParameterExpressionBuilders.Add( + new CustomParameterExpressionBuilder( + t => t.GetLocalState("foo")!)); + } + } } diff --git a/src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderSchemaTest.snap b/src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderSchemaTest.snap new file mode 100644 index 00000000000..992a4f417e8 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderSchemaTest.snap @@ -0,0 +1,13 @@ +schema { + query: QueryWithScopedExpressionBuilder +} + +type QueryWithScopedExpressionBuilder { + bar: String! +} + +"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`." +directive @defer("Deferred when true." if: Boolean "If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." label: String) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`." +directive @stream("Streamed when true." if: Boolean "The initial elements that shall be send down to the consumer." initialCount: Int! = 0 "If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." label: String) on FIELD diff --git a/src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderTest.snap b/src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderTest.snap new file mode 100644 index 00000000000..621ed92e831 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Resolvers/__snapshots__/ResolverCompilerTests.ScopedExpressionBuilderTest.snap @@ -0,0 +1,5 @@ +{ + "data": { + "bar": "Abc" + } +}