From e2274bea42c0cef989476ffba22a73657c9b4133 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Mon, 1 May 2023 22:58:18 +0200 Subject: [PATCH] Fusion Builder Refinements --- .../FusionGatewayBuilder.cs | 35 +++++++++ .../FusionRequestExecutorBuilderExtensions.cs | 77 ++++++++++++++++--- .../test/Core.Tests/DemoIntegrationTests.cs | 1 + 3 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionGatewayBuilder.cs diff --git a/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionGatewayBuilder.cs b/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionGatewayBuilder.cs new file mode 100644 index 00000000000..976fa920aab --- /dev/null +++ b/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionGatewayBuilder.cs @@ -0,0 +1,35 @@ +using HotChocolate.Execution.Configuration; + +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// A builder for configuring a GraphQL gateway. +/// +public sealed class FusionGatewayBuilder +{ + /// + /// Initializes a new instance of . + /// + /// + /// The underlying request executor builder. + /// + public FusionGatewayBuilder(IRequestExecutorBuilder coreBuilder) + { + CoreBuilder = coreBuilder; + } + + /// + /// Gets the name of the schema. + /// + public string Name => CoreBuilder.Name; + + /// + /// Gets the application services. + /// + public IServiceCollection Services => CoreBuilder.Services; + + /// + /// Gets the underlying request executor builder. + /// + internal IRequestExecutorBuilder CoreBuilder { get; } +} diff --git a/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs b/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs index 75a0cbb33bd..28aa0a2d1de 100644 --- a/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs +++ b/src/HotChocolate/Fusion/src/Core/DependencyInjection/FusionRequestExecutorBuilderExtensions.cs @@ -1,4 +1,5 @@ using HotChocolate; +using HotChocolate.Execution; using HotChocolate.Execution.Configuration; using HotChocolate.Fusion; using HotChocolate.Fusion.Clients; @@ -23,6 +24,9 @@ public static class FusionRequestExecutorBuilderExtensions /// /// The fusion graph document. /// + /// + /// The name of the fusion graph. + /// /// /// Returns the that can be used to configure the Gateway. /// @@ -30,9 +34,10 @@ public static class FusionRequestExecutorBuilderExtensions /// is null or /// is null. /// - public static IRequestExecutorBuilder AddFusionGatewayServer( + public static FusionGatewayBuilder AddFusionGatewayServer( this IServiceCollection services, - DocumentNode fusionGraphDocument) + DocumentNode fusionGraphDocument, + string? graphName = default) { if (services is null) { @@ -45,7 +50,8 @@ public static class FusionRequestExecutorBuilderExtensions } return services.AddFusionGatewayServer( - _ => new ValueTask(fusionGraphDocument)); + _ => new ValueTask(fusionGraphDocument), + graphName: graphName); } /// @@ -57,6 +63,9 @@ public static class FusionRequestExecutorBuilderExtensions /// /// The path to the fusion graph package file or fusion graph file. /// + /// + /// The name of the fusion graph. + /// /// /// If set to true the fusion graph file will be watched for updates and /// the schema is rebuild whenever the file changes. @@ -69,9 +78,10 @@ public static class FusionRequestExecutorBuilderExtensions /// is null or /// is equals to . /// - public static IRequestExecutorBuilder AddFusionGatewayServer( + public static FusionGatewayBuilder AddFusionGatewayServer( this IServiceCollection services, string fusionGraphFile, + string? graphName = default, bool watchFileForUpdates = false) { if (services is null) @@ -84,11 +94,13 @@ public static class FusionRequestExecutorBuilderExtensions throw new ArgumentNullException(nameof(fusionGraphFile)); } - var builder = services.AddFusionGatewayServer(ct => LoadDocumentAsync(fusionGraphFile, ct)); + var builder = services.AddFusionGatewayServer( + ct => LoadDocumentAsync(fusionGraphFile, ct), + graphName: graphName); if (watchFileForUpdates) { - builder.AddTypeModule(_ => new FileWatcherTypeModule(fusionGraphFile)); + builder.CoreBuilder.AddTypeModule(_ => new FileWatcherTypeModule(fusionGraphFile)); } return builder; @@ -103,6 +115,9 @@ public static class FusionRequestExecutorBuilderExtensions /// /// A delegate that is used to resolve a fusion graph document. /// + /// + /// The name of the fusion graph. + /// /// /// Returns the that can be used to configure the Gateway. /// @@ -110,9 +125,10 @@ public static class FusionRequestExecutorBuilderExtensions /// is null or /// is null. /// - public static IRequestExecutorBuilder AddFusionGatewayServer( + public static FusionGatewayBuilder AddFusionGatewayServer( this IServiceCollection services, - ResolveFusionGraphDocAsync fusionGraphResolver) + ResolveFusionGraphDocAsync fusionGraphResolver, + string? graphName = default) { if (services is null) { @@ -124,8 +140,8 @@ public static class FusionRequestExecutorBuilderExtensions throw new ArgumentNullException(nameof(fusionGraphResolver)); } - return services - .AddGraphQLServer() + var builder = services + .AddGraphQLServer(graphName) .UseField(next => next) .UseDefaultGatewayPipeline() .AddOperationCompilerOptimizer() @@ -157,6 +173,8 @@ public static class FusionRequestExecutorBuilderExtensions sc.TryAddSingleton(); }); }); + + return new FusionGatewayBuilder(builder); } private static IRequestExecutorBuilder UseDefaultGatewayPipeline( @@ -238,6 +256,45 @@ public static class FusionRequestExecutorBuilderExtensions return Utf8GraphQLParser.Parse(sourceText); } } + + /// + /// Builds a from the specified + /// . + /// + /// + /// The . + /// + /// + /// The name of the graph that shall be built. + /// + /// + /// The cancellation token. + /// + /// + internal static ValueTask BuildRequestExecutorAsync( + this FusionGatewayBuilder builder, + string? graphName = default, + CancellationToken cancellationToken = default) + => builder.CoreBuilder.BuildRequestExecutorAsync(graphName, cancellationToken); + + /// + /// Builds a from the specified . + /// + /// + /// The . + /// + /// + /// The name of the graph that shall be built. + /// + /// + /// The cancellation token. + /// + /// + internal static ValueTask BuildSchemaAsync( + this FusionGatewayBuilder builder, + string? graphName = default, + CancellationToken cancellationToken = default) + => builder.CoreBuilder.BuildSchemaAsync(graphName, cancellationToken); } static file class FileExtensions diff --git a/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs b/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs index 1afdac05917..306a903b326 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs +++ b/src/HotChocolate/Fusion/test/Core.Tests/DemoIntegrationTests.cs @@ -946,6 +946,7 @@ public async Task Hot_Reload() .AddSingleton(demoProject.HttpClientFactory) .AddSingleton(demoProject.WebSocketConnectionFactory) .AddFusionGatewayServer(_ => new(SchemaFormatter.FormatAsDocument(fusionGraph))) + .CoreBuilder .AddTypeModule(_ => reloadTypeModule) .Services .BuildServiceProvider();