From 3501daababd03ec2f6ae010565972e5cd7810173 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Wed, 1 Nov 2023 09:24:58 +0100 Subject: [PATCH] Remove ReadOnly Schema Options Wrapper (#6653) --- .../Types/Configuration/TypeInterceptor.cs | 24 ++- .../Core/src/Types/IReadOnlySchemaOptions.cs | 147 ++++++++++++++---- .../Core/src/Types/ReadOnlySchemaOptions.cs | 139 ----------------- .../Core/src/Types/SchemaOptions.cs | 11 +- .../ReadOnlySchemaOptionsTests.cs | 135 ---------------- 5 files changed, 146 insertions(+), 310 deletions(-) delete mode 100644 src/HotChocolate/Core/src/Types/ReadOnlySchemaOptions.cs delete mode 100644 src/HotChocolate/Core/test/Types.Tests/Configuration/ReadOnlySchemaOptionsTests.cs diff --git a/src/HotChocolate/Core/src/Types/Configuration/TypeInterceptor.cs b/src/HotChocolate/Core/src/Types/Configuration/TypeInterceptor.cs index 0ef9dbf149f..19303304b13 100644 --- a/src/HotChocolate/Core/src/Types/Configuration/TypeInterceptor.cs +++ b/src/HotChocolate/Core/src/Types/Configuration/TypeInterceptor.cs @@ -31,11 +31,12 @@ public abstract class TypeInterceptor internal virtual void SetSiblings(TypeInterceptor[] all) { } - [Obsolete("The schema builder is obsolete and will be removed in the next version.", error: true)] - public virtual void OnBeforeCreateSchema_( + [Obsolete("This hook is deprecated and will be removed in the next release.")] + internal virtual void OnBeforeCreateSchema( IDescriptorContext context, ISchemaBuilder schemaBuilder) { } + // note: this hook is a legacy hook and will be removed once the new schema building API is completed. /// /// This hook is invoked before anything else any allows for additional modification /// with the schema builder. @@ -48,7 +49,12 @@ public virtual void OnBeforeCreateSchema_( /// internal virtual void OnBeforeCreateSchemaInternal( IDescriptorContext context, - ISchemaBuilder schemaBuilder) { } + ISchemaBuilder schemaBuilder) + { +#pragma warning disable CS0618 // Type or member is obsolete + OnBeforeCreateSchema(context, schemaBuilder); +#pragma warning restore CS0618 // Type or member is obsolete + } internal virtual void InitializeContext( IDescriptorContext context, @@ -265,9 +271,10 @@ public virtual void OnValidateType( public virtual void OnTypesCompleted() { } - [Obsolete("The schema builder is obsolete and will be removed in the next version.", error: true)] - public virtual void OnAfterCreateSchema_(IDescriptorContext context, ISchema schema) { } + [Obsolete("This hook is deprecated and will be removed in the next release.")] + public virtual void OnAfterCreateSchema(IDescriptorContext context, ISchema schema) { } + // note: this hook is a legacy hook and will be removed once the new schema building API is completed. /// /// This hook is invoked after schema is fully created and gives access /// to the created schema object. @@ -278,7 +285,12 @@ public virtual void OnAfterCreateSchema_(IDescriptorContext context, ISchema sch /// /// The created schema. /// - internal virtual void OnAfterCreateSchemaInternal(IDescriptorContext context, ISchema schema) { } + internal virtual void OnAfterCreateSchemaInternal(IDescriptorContext context, ISchema schema) + { +#pragma warning disable CS0618 // Type or member is obsolete + OnAfterCreateSchema(context, schema); +#pragma warning restore CS0618 // Type or member is obsolete + } /// /// This hook is invoked if an error occured during schema creation. diff --git a/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs b/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs index 2d70e9bacb8..306d0d42b15 100644 --- a/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs +++ b/src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs @@ -13,84 +13,175 @@ namespace HotChocolate; /// public interface IReadOnlySchemaOptions { - /// + /// + /// Gets or sets the name of the query type. + /// string? QueryTypeName { get; } - /// + /// + /// Gets or sets the name of the mutation type. + /// string? MutationTypeName { get; } - /// + /// + /// Gets or sets the name of the subscription type. + /// string? SubscriptionTypeName { get; } - /// + /// + /// Defines if the schema allows the query type to be omitted. + /// bool StrictValidation { get; } - /// + /// + /// Defines if the CSharp XML documentation shall be integrated. + /// bool UseXmlDocumentation { get; } - /// + /// + /// A delegate which defines the name of the XML documentation file to be read. + /// Only used if is true. + /// Func? ResolveXmlDocumentationFileName { get; } - /// + /// + /// Defines if fields shall be sorted by name. + /// Default: false + /// bool SortFieldsByName { get; } - /// + /// + /// Defines if syntax nodes shall be preserved on the type system objects + /// bool PreserveSyntaxNodes { get; } - /// + /// + /// Defines if types shall be removed from the schema that are + /// unreachable from the root types. + /// bool RemoveUnreachableTypes { get; } - /// + /// + /// Defines the default binding behavior. + /// BindingBehavior DefaultBindingBehavior { get; } - /// + /// + /// Defines which members shall be by default inferred as GraphQL fields. + /// This default applies to and . + /// FieldBindingFlags DefaultFieldBindingFlags { get; } - /// + /// + /// Defines on which fields a middleware pipeline can be applied on. + /// FieldMiddlewareApplication FieldMiddleware { get; } - /// + /// + /// Defines if the experimental directive introspection feature shall be enabled. + /// bool EnableDirectiveIntrospection { get; } - /// + /// + /// The default directive visibility when directive introspection is enabled. + /// DirectiveVisibility DefaultDirectiveVisibility { get; } - /// + /// + /// Defines that the default resolver execution strategy. + /// ExecutionStrategy DefaultResolverStrategy { get; } - /// + /// + /// Defines if the order of important middleware components shall be validated. + /// bool ValidatePipelineOrder { get; } - - /// + + /// + /// Defines if the runtime types of types shall be validated. + /// bool StrictRuntimeTypeValidation { get; } - /// + /// + /// Defines a delegate that determines if a runtime + /// is an instance of an . + /// IsOfTypeFallback? DefaultIsOfTypeCheck { get; } - /// + /// + /// Defines if the OneOf spec RFC is enabled. This feature is experimental. + /// bool EnableOneOf { get; } - /// + /// + /// Defines if the schema building process shall validate that all nodes are resolvable through `node`. + /// bool EnsureAllNodesCanBeResolved { get; } - /// + /// + /// Defines if flag enums should be inferred as object value nodes + /// + /// + /// Given the following enum + ///
+ /// + /// [Flags] + /// public enum Example { First, Second, Third } + /// + /// public class Query { public Example Loopback(Example input) => input; + /// + ///
+ /// The following schema is produced + ///
+ /// + /// type Query { + /// loopback(input: ExampleFlagsInput!): ExampleFlags + /// } + /// + /// type ExampleFlags { + /// isFirst: Boolean! + /// isSecond: Boolean! + /// isThird: Boolean! + /// } + /// + /// input ExampleFlagsInput { + /// isFirst: Boolean + /// isSecond: Boolean + /// isThird: Boolean + /// } + /// + ///
bool EnableFlagEnums { get; } - /// + /// + /// Enables the @defer directive. + /// Defer and stream both are at the moment preview features. + /// bool EnableDefer { get; } - /// + /// + /// Enables the @stream directive. + /// Defer and stream both are at the moment preview features. + /// bool EnableStream { get; } - /// + /// + /// Specifies the maximum allowed nodes that can be fetched at once through the nodes field. + /// int MaxAllowedNodeBatchSize { get; } - /// + /// + /// Specified if the leading I shall be stripped from the interface name. + /// bool StripLeadingIFromInterface { get; } - /// + /// + /// Specifies that the true nullability proto type shall be enabled. + /// bool EnableTrueNullability { get; } - /// + /// + /// Specifies that the @tag directive shall be registered with the type system. + /// bool EnableTag { get; } } diff --git a/src/HotChocolate/Core/src/Types/ReadOnlySchemaOptions.cs b/src/HotChocolate/Core/src/Types/ReadOnlySchemaOptions.cs deleted file mode 100644 index 8b237868478..00000000000 --- a/src/HotChocolate/Core/src/Types/ReadOnlySchemaOptions.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System; -using System.Reflection; -using HotChocolate.Execution; -using HotChocolate.Types; - -#nullable enable - -namespace HotChocolate.Configuration; - -/// -/// Represents read-only schema options. -/// -public class ReadOnlySchemaOptions : IReadOnlySchemaOptions -{ - /// - /// Initializes a new instance of . - /// - /// - /// The options that shall be wrapped as read-only options. - /// - /// - /// is null. - /// - public ReadOnlySchemaOptions(IReadOnlySchemaOptions options) - { - if (options is null) - { - throw new ArgumentNullException(nameof(options)); - } - - QueryTypeName = options.QueryTypeName ?? "Query"; - MutationTypeName = options.MutationTypeName ?? "Mutation"; - SubscriptionTypeName = options.SubscriptionTypeName ?? "Subscription"; - StrictValidation = options.StrictValidation; - SortFieldsByName = options.SortFieldsByName; - UseXmlDocumentation = options.UseXmlDocumentation; - ResolveXmlDocumentationFileName = options.ResolveXmlDocumentationFileName; - RemoveUnreachableTypes = options.RemoveUnreachableTypes; - DefaultBindingBehavior = options.DefaultBindingBehavior; - DefaultFieldBindingFlags = options.DefaultFieldBindingFlags; - FieldMiddleware = options.FieldMiddleware; - PreserveSyntaxNodes = options.PreserveSyntaxNodes; - EnableDirectiveIntrospection = options.EnableDirectiveIntrospection; - DefaultDirectiveVisibility = options.DefaultDirectiveVisibility; - DefaultResolverStrategy = options.DefaultResolverStrategy; - ValidatePipelineOrder = options.ValidatePipelineOrder; - StrictRuntimeTypeValidation = options.StrictRuntimeTypeValidation; - DefaultIsOfTypeCheck = options.DefaultIsOfTypeCheck; - EnableOneOf = options.EnableOneOf; - EnsureAllNodesCanBeResolved = options.EnsureAllNodesCanBeResolved; - EnableFlagEnums = options.EnableFlagEnums; - EnableDefer = options.EnableDefer; - EnableStream = options.EnableStream; - MaxAllowedNodeBatchSize = options.MaxAllowedNodeBatchSize; - StripLeadingIFromInterface = options.StripLeadingIFromInterface; - EnableTrueNullability = options.EnableTrueNullability; - EnableTag = options.EnableTag; - } - - /// - public string QueryTypeName { get; } - - /// - public string MutationTypeName { get; } - - /// - public string SubscriptionTypeName { get; } - - /// - public bool StrictValidation { get; } - - /// - public bool UseXmlDocumentation { get; } - - /// - public Func? ResolveXmlDocumentationFileName { get; } - - /// - public bool SortFieldsByName { get; } - - /// - public bool PreserveSyntaxNodes { get; } - - /// - public bool RemoveUnreachableTypes { get; } - - /// - public BindingBehavior DefaultBindingBehavior { get; } - - /// - public FieldBindingFlags DefaultFieldBindingFlags { get; } - - /// - public FieldMiddlewareApplication FieldMiddleware { get; } - - /// - public bool EnableDirectiveIntrospection { get; } - - /// - public DirectiveVisibility DefaultDirectiveVisibility { get; } - - public ExecutionStrategy DefaultResolverStrategy { get; } - - /// - public bool ValidatePipelineOrder { get; } - - /// - public bool StrictRuntimeTypeValidation { get; } - - /// - public IsOfTypeFallback? DefaultIsOfTypeCheck { get; } - - /// - public bool EnableOneOf { get; } - - /// - public bool EnsureAllNodesCanBeResolved { get; } - - /// - public bool EnableFlagEnums { get; } - - /// - public bool EnableDefer { get; } - - /// - public bool EnableStream { get; } - - /// - public int MaxAllowedNodeBatchSize { get; } - - /// - public bool StripLeadingIFromInterface { get; } - - /// - public bool EnableTrueNullability { get; } - - /// - public bool EnableTag { get; } -} diff --git a/src/HotChocolate/Core/src/Types/SchemaOptions.cs b/src/HotChocolate/Core/src/Types/SchemaOptions.cs index 74d08213d78..e32e9138c59 100644 --- a/src/HotChocolate/Core/src/Types/SchemaOptions.cs +++ b/src/HotChocolate/Core/src/Types/SchemaOptions.cs @@ -15,11 +15,16 @@ public class SchemaOptions : IReadOnlySchemaOptions { private BindingBehavior _defaultBindingBehavior = BindingBehavior.Implicit; private FieldBindingFlags _defaultFieldBindingFlags = FieldBindingFlags.Instance; + private string? _queryTypeName; /// /// Gets or sets the name of the query type. /// - public string? QueryTypeName { get; set; } + public string? QueryTypeName + { + get => _queryTypeName; + set => _queryTypeName = value; + } /// /// Gets or sets the name of the mutation type. @@ -143,7 +148,9 @@ public FieldBindingFlags DefaultFieldBindingFlags /// public bool EnableOneOf { get; set; } - /// + /// + /// Defines if the schema building process shall validate that all nodes are resolvable through `node`. + /// public bool EnsureAllNodesCanBeResolved { get; set; } /// diff --git a/src/HotChocolate/Core/test/Types.Tests/Configuration/ReadOnlySchemaOptionsTests.cs b/src/HotChocolate/Core/test/Types.Tests/Configuration/ReadOnlySchemaOptionsTests.cs deleted file mode 100644 index 43528cc709c..00000000000 --- a/src/HotChocolate/Core/test/Types.Tests/Configuration/ReadOnlySchemaOptionsTests.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using HotChocolate.Execution; -using HotChocolate.Types; -using Snapshooter.Xunit; -using Xunit; - -namespace HotChocolate.Configuration; - -public class ReadOnlySchemaOptionsTests -{ - [Fact] - public void Copy_Options() - { - // arrange - var options = new SchemaOptions - { - QueryTypeName = "A", - MutationTypeName = "B", - SubscriptionTypeName = "C", - StrictValidation = false, - SortFieldsByName = true, - UseXmlDocumentation = false, - DefaultBindingBehavior = BindingBehavior.Explicit, - FieldMiddleware = FieldMiddlewareApplication.AllFields, - PreserveSyntaxNodes = true, - StrictRuntimeTypeValidation = true, - MaxAllowedNodeBatchSize = 20, - EnableOneOf = true, - DefaultDirectiveVisibility = DirectiveVisibility.Public, - EnableDirectiveIntrospection = true, - DefaultFieldBindingFlags = FieldBindingFlags.InstanceAndStatic, - ValidatePipelineOrder = true, - EnableDefer = true, - EnableStream = true, - EnableFlagEnums = true, - EnsureAllNodesCanBeResolved = true, - RemoveUnreachableTypes = true, - DefaultResolverStrategy = ExecutionStrategy.Serial - }; - - // act - var copied = new ReadOnlySchemaOptions(options); - var writableCopy = SchemaOptions.FromOptions(copied); - - // assert - copied.MatchSnapshot(); - writableCopy.MatchSnapshot(); - } - - [Fact] - public void Copy_Options_EnableOneOf_EnableDirectiveIntrospection() - { - // arrange - var options = new SchemaOptions - { - QueryTypeName = "A", - MutationTypeName = "B", - SubscriptionTypeName = "C", - StrictValidation = false, - SortFieldsByName = true, - UseXmlDocumentation = false, - DefaultBindingBehavior = BindingBehavior.Explicit, - FieldMiddleware = FieldMiddlewareApplication.AllFields, - PreserveSyntaxNodes = true, - EnableOneOf = true, - EnableDirectiveIntrospection = true - }; - - // act - var copied = new ReadOnlySchemaOptions(options); - var writableCopy = SchemaOptions.FromOptions(copied); - - // assert - copied.MatchSnapshot(); - writableCopy.MatchSnapshot(); - } - - [Fact] - public void Copy_Options_ResolveXmlDocumentationFileName() - { - // arrange - var options = new SchemaOptions - { - QueryTypeName = "A", - MutationTypeName = "B", - SubscriptionTypeName = "C", - StrictValidation = false, - SortFieldsByName = true, - UseXmlDocumentation = false, - ResolveXmlDocumentationFileName = assembly => "docs.xml", - DefaultBindingBehavior = BindingBehavior.Explicit, - FieldMiddleware = FieldMiddlewareApplication.AllFields, - PreserveSyntaxNodes = true - }; - - // act - var copied = new ReadOnlySchemaOptions(options); - var writableCopy = SchemaOptions.FromOptions(copied); - - // assert - Assert.Same( - options.ResolveXmlDocumentationFileName, - copied.ResolveXmlDocumentationFileName); - - Assert.Same( - copied.ResolveXmlDocumentationFileName, - writableCopy.ResolveXmlDocumentationFileName); - } - - [Fact] - public void Copy_Options_Defaults() - { - // arrange - var options = new SchemaOptions(); - - // act - var copied = new ReadOnlySchemaOptions(options); - var writableCopy = SchemaOptions.FromOptions(copied); - - // assert - copied.MatchSnapshot(); - writableCopy.MatchSnapshot(); - } - - [Fact] - public void Create_Options_Null() - { - // arrange - // act - Action action = () => new ReadOnlySchemaOptions(null); - - // assert - Assert.Throws(action); - } -}