From 8e8a463a1c159549f948fc2394d247f3b7aea34e Mon Sep 17 00:00:00 2001 From: Konstantin Savosteev Date: Thu, 5 Dec 2024 10:57:45 +0200 Subject: [PATCH] VCST-2241: prepare schema for partition (#18) --- .../ApplicationBuilderExtensions.cs | 36 +++++++++++++++++++ .../Infrastructure/SchemaFactory.cs | 33 ++++++++++++----- .../Infrastructure/ScopedSchemaFactory.cs | 32 +++++++++++++++++ .../ModuleConstants.cs | 7 ++++ .../VirtoCommerce.Xapi.Core.csproj | 1 + src/VirtoCommerce.Xapi.Web/Module.cs | 27 +++++--------- .../VirtoCommerce.Xapi.Web.csproj | 1 - 7 files changed, 110 insertions(+), 27 deletions(-) create mode 100644 src/VirtoCommerce.Xapi.Core/Extensions/ApplicationBuilderExtensions.cs create mode 100644 src/VirtoCommerce.Xapi.Core/Infrastructure/ScopedSchemaFactory.cs diff --git a/src/VirtoCommerce.Xapi.Core/Extensions/ApplicationBuilderExtensions.cs b/src/VirtoCommerce.Xapi.Core/Extensions/ApplicationBuilderExtensions.cs new file mode 100644 index 0000000..c352258 --- /dev/null +++ b/src/VirtoCommerce.Xapi.Core/Extensions/ApplicationBuilderExtensions.cs @@ -0,0 +1,36 @@ +using GraphQL.Server.Ui.Playground; +using GraphQL.Types; +using Microsoft.AspNetCore.Builder; + +namespace VirtoCommerce.Xapi.Core.Extensions; + +public static class ApplicationBuilderExtensions +{ + public static IApplicationBuilder UseSchemaGraphQL(this IApplicationBuilder builder, bool schemaIntrospectionEnabled = true, string schemaPath = null) + where TSchema : ISchema + { + var graphQlPath = "/graphql"; + if (!string.IsNullOrEmpty(schemaPath)) + { + graphQlPath = $"{graphQlPath}/{schemaPath}"; + } + + var playgroundPath = "/ui/playground"; + if (!string.IsNullOrEmpty(schemaPath)) + { + playgroundPath = $"{playgroundPath}/{schemaPath}"; + } + + builder.UseGraphQL(path: graphQlPath); + if (schemaIntrospectionEnabled) + { + builder.UseGraphQLPlayground(new PlaygroundOptions + { + GraphQLEndPoint = graphQlPath, + }, + path: playgroundPath); + } + + return builder; + } +} diff --git a/src/VirtoCommerce.Xapi.Core/Infrastructure/SchemaFactory.cs b/src/VirtoCommerce.Xapi.Core/Infrastructure/SchemaFactory.cs index 37a49d8..a62f929 100644 --- a/src/VirtoCommerce.Xapi.Core/Infrastructure/SchemaFactory.cs +++ b/src/VirtoCommerce.Xapi.Core/Infrastructure/SchemaFactory.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using GraphQL; using GraphQL.Conversion; using GraphQL.Instrumentation; @@ -61,15 +62,10 @@ public SchemaFactory(IEnumerable schemaBuilders, IServiceProvide public ISchema GetSchema() { - var schema = new Schema(_services) - { - Query = new ObjectGraphType { Name = "Query" }, - Mutation = new ObjectGraphType { Name = "Mutations" }, - Subscription = new ObjectGraphType { Name = "Subscriptions" }, - Filter = _schemaFilter, - }; + var schema = CreateSchema(_services, _schemaFilter); - foreach (var builder in _schemaBuilders) + var schemaBuilders = GetSchemaBuilders(); + foreach (var builder in schemaBuilders) { builder.Build(schema); } @@ -99,9 +95,30 @@ public ISchema GetSchema() schema.Mutation = null; } + if (schema.Subscription.Fields.Count == 0) + { + schema.Subscription = null; + } + return schema; } + protected virtual Schema CreateSchema(IServiceProvider services, ISchemaFilter schemaFilter) + { + return new Schema(services) + { + Query = new ObjectGraphType { Name = "Query" }, + Mutation = new ObjectGraphType { Name = "Mutations" }, + Subscription = new ObjectGraphType { Name = "Subscriptions" }, + Filter = schemaFilter, + }; + } + + protected virtual List GetSchemaBuilders() + { + return _schemaBuilders.ToList(); + } + public void Initialize() { _schema.Value.Initialize(); diff --git a/src/VirtoCommerce.Xapi.Core/Infrastructure/ScopedSchemaFactory.cs b/src/VirtoCommerce.Xapi.Core/Infrastructure/ScopedSchemaFactory.cs new file mode 100644 index 0000000..ba96788 --- /dev/null +++ b/src/VirtoCommerce.Xapi.Core/Infrastructure/ScopedSchemaFactory.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using GraphQL.Introspection; + +namespace VirtoCommerce.Xapi.Core.Infrastructure +{ + public class ScopedSchemaFactory : SchemaFactory + { + public ScopedSchemaFactory( + IEnumerable schemaBuilders, + IServiceProvider services, + ISchemaFilter schemaFilter) + : base(schemaBuilders, services, schemaFilter) + { + } + + protected override List GetSchemaBuilders() + { + var schemaBuilders = base.GetSchemaBuilders(); + + // find all builders inside this assembly + var currentAssembly = typeof(TMarker).Assembly; + + var subSchemaBuilders = schemaBuilders + .Where(p => p.GetType().Assembly == currentAssembly) + .ToList(); + + return subSchemaBuilders; + } + } +} diff --git a/src/VirtoCommerce.Xapi.Core/ModuleConstants.cs b/src/VirtoCommerce.Xapi.Core/ModuleConstants.cs index 7ee5ddf..70e91ab 100644 --- a/src/VirtoCommerce.Xapi.Core/ModuleConstants.cs +++ b/src/VirtoCommerce.Xapi.Core/ModuleConstants.cs @@ -5,6 +5,13 @@ namespace VirtoCommerce.Xapi.Core { public static class ModuleConstants { + public static class ConfigKeys + { + public const string GraphQlPlayground = "VirtoCommerce:GraphQLPlayground"; + public const string GraphQlWebSocket = "VirtoCommerce:GraphQLWebSocket"; + public const string Stores = "VirtoCommerce:Stores"; + } + public static class Connections { public const int DefaultPageSize = 20; diff --git a/src/VirtoCommerce.Xapi.Core/VirtoCommerce.Xapi.Core.csproj b/src/VirtoCommerce.Xapi.Core/VirtoCommerce.Xapi.Core.csproj index 739aa56..667f92b 100644 --- a/src/VirtoCommerce.Xapi.Core/VirtoCommerce.Xapi.Core.csproj +++ b/src/VirtoCommerce.Xapi.Core/VirtoCommerce.Xapi.Core.csproj @@ -25,6 +25,7 @@ + diff --git a/src/VirtoCommerce.Xapi.Web/Module.cs b/src/VirtoCommerce.Xapi.Web/Module.cs index 919b1ad..7d39165 100644 --- a/src/VirtoCommerce.Xapi.Web/Module.cs +++ b/src/VirtoCommerce.Xapi.Web/Module.cs @@ -8,7 +8,6 @@ using VirtoCommerce.Platform.Core.Modularity; using VirtoCommerce.Platform.Core.Settings; using VirtoCommerce.TaxModule.Core.Model; -using VirtoCommerce.Xapi.Core; using VirtoCommerce.Xapi.Core.Extensions; using VirtoCommerce.Xapi.Core.Infrastructure; using VirtoCommerce.Xapi.Core.Infrastructure.Validation; @@ -16,6 +15,7 @@ using VirtoCommerce.Xapi.Core.Subscriptions; using VirtoCommerce.Xapi.Data.Extensions; using VirtoCommerce.Xapi.Web.Extensions; +using static VirtoCommerce.Xapi.Core.ModuleConstants; namespace VirtoCommerce.Xapi.Web { @@ -24,15 +24,11 @@ public class Module : IModule, IHasConfiguration public ManifestModuleInfo ModuleInfo { get; set; } public IConfiguration Configuration { get; set; } - private const string _graphQlPlaygroundConfigKey = "VirtoCommerce:GraphQLPlayground"; - private const string _graphQlWebSocketConfigKey = "VirtoCommerce:GraphQLWebSocket"; - private const string _storesConfigKey = "VirtoCommerce:Stores"; - private bool IsSchemaIntrospectionEnabled { get { - return Configuration.GetValue($"{_graphQlPlaygroundConfigKey}:{nameof(GraphQLPlaygroundOptions.Enable)}"); + return Configuration.GetValue($"{ConfigKeys.GraphQlPlayground}:{nameof(GraphQLPlaygroundOptions.Enable)}"); } } @@ -72,9 +68,9 @@ public void Initialize(IServiceCollection serviceCollection) serviceCollection.AddAutoMapper(ModuleInfo.Assembly); - serviceCollection.Configure(Configuration.GetSection(_graphQlPlaygroundConfigKey)); - serviceCollection.Configure(Configuration.GetSection(_graphQlWebSocketConfigKey)); - serviceCollection.Configure(Configuration.GetSection(_storesConfigKey)); + serviceCollection.Configure(Configuration.GetSection(ConfigKeys.GraphQlPlayground)); + serviceCollection.Configure(Configuration.GetSection(ConfigKeys.GraphQlWebSocket)); + serviceCollection.Configure(Configuration.GetSection(ConfigKeys.Stores)); } public void PostInitialize(IApplicationBuilder appBuilder) @@ -88,18 +84,13 @@ public void PostInitialize(IApplicationBuilder appBuilder) appBuilder.UseGraphQLWebSockets(); // add http for Schema at default url /graphql - appBuilder.UseGraphQL(); - - if (IsSchemaIntrospectionEnabled) - { - // Use GraphQL Playground at default URL /ui/playground - appBuilder.UseGraphQLPlayground(); - } + // use GraphQL Playground at default URL /ui/playground + appBuilder.UseSchemaGraphQL(IsSchemaIntrospectionEnabled); // settings var settingsRegistrar = serviceProvider.GetRequiredService(); - settingsRegistrar.RegisterSettings(ModuleConstants.Settings.General.AllSettings, ModuleInfo.Id); - settingsRegistrar.RegisterSettingsForType(ModuleConstants.Settings.StoreLevelSettings, nameof(Store)); + settingsRegistrar.RegisterSettings(Settings.General.AllSettings, ModuleInfo.Id); + settingsRegistrar.RegisterSettingsForType(Settings.StoreLevelSettings, nameof(Store)); } public void Uninstall() diff --git a/src/VirtoCommerce.Xapi.Web/VirtoCommerce.Xapi.Web.csproj b/src/VirtoCommerce.Xapi.Web/VirtoCommerce.Xapi.Web.csproj index 4ab9951..bea56c9 100644 --- a/src/VirtoCommerce.Xapi.Web/VirtoCommerce.Xapi.Web.csproj +++ b/src/VirtoCommerce.Xapi.Web/VirtoCommerce.Xapi.Web.csproj @@ -8,7 +8,6 @@ Library -