From 0a59bf23b688afefa6bd890c9782de2468c285d5 Mon Sep 17 00:00:00 2001 From: Jesper Balle Date: Mon, 14 Apr 2025 15:03:06 +0200 Subject: [PATCH 1/2] Use SitecoreGraphQlClientOptions for GraphQLHttpClient and support Configure --- .../GraphQlConfigurationExtensions.cs | 27 ++++++++++++------- .../GraphQlConfigurationExtensionsFixture.cs | 18 ++++++++----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/Sitecore.AspNetCore.SDK.GraphQL/Extensions/GraphQlConfigurationExtensions.cs b/src/Sitecore.AspNetCore.SDK.GraphQL/Extensions/GraphQlConfigurationExtensions.cs index 6adb9b4..c58daaf 100644 --- a/src/Sitecore.AspNetCore.SDK.GraphQL/Extensions/GraphQlConfigurationExtensions.cs +++ b/src/Sitecore.AspNetCore.SDK.GraphQL/Extensions/GraphQlConfigurationExtensions.cs @@ -1,6 +1,7 @@ using GraphQL.Client.Abstractions; using GraphQL.Client.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Sitecore.AspNetCore.SDK.GraphQL.Client.Models; using Sitecore.AspNetCore.SDK.GraphQL.Exceptions; using Sitecore.AspNetCore.SDK.GraphQL.Properties; @@ -23,12 +24,13 @@ public static IServiceCollection AddGraphQlClient(this IServiceCollection servic ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(configuration); - services.Configure(configuration); + services.Configure(x => TryGetConfiguration(x, configuration)); - SitecoreGraphQlClientOptions options = TryGetConfiguration(configuration); - - services.AddSingleton(_ => + services.AddSingleton(sp => { + var options = sp.GetRequiredService>().Value; + ValidateOptions(options); + if (!string.IsNullOrWhiteSpace(options.ContextId)) { options.EndPoint = options.EndPoint.AddQueryString( @@ -36,7 +38,7 @@ public static IServiceCollection AddGraphQlClient(this IServiceCollection servic options.ContextId); } - GraphQLHttpClient graphQlHttpClient = new(options.EndPoint!, options.GraphQlJsonSerializer); + GraphQLHttpClient graphQlHttpClient = new(options, options.GraphQlJsonSerializer); if (!string.IsNullOrWhiteSpace(options.ApiKey)) { @@ -49,11 +51,20 @@ public static IServiceCollection AddGraphQlClient(this IServiceCollection servic return services; } - private static SitecoreGraphQlClientOptions TryGetConfiguration(Action configuration) + private static SitecoreGraphQlClientOptions TryGetConfiguration(SitecoreGraphQlClientOptions options, Action configuration) { - SitecoreGraphQlClientOptions options = new(); configuration.Invoke(options); + if (options.EndPoint == null && !string.IsNullOrWhiteSpace(options.ContextId)) + { + options.EndPoint = SitecoreGraphQlClientOptions.DefaultEdgeEndpoint; + } + + return options; + } + + private static void ValidateOptions(SitecoreGraphQlClientOptions options) + { if (string.IsNullOrWhiteSpace(options.ApiKey) && string.IsNullOrWhiteSpace(options.ContextId)) { throw new InvalidGraphQlConfigurationException(Resources.Exception_MissingApiKeyAndContextId); @@ -67,7 +78,5 @@ private static SitecoreGraphQlClientOptions TryGetConfiguration(Action act = - () => Substitute.For().AddGraphQlClient(_ => { }); + var services = new ServiceCollection(); + services.AddGraphQlClient(_ => { }); + var sp = services.BuildServiceProvider(); + Func act = () => sp.GetRequiredService(); act.Should().Throw() .WithMessage(Resources.Exception_MissingApiKeyAndContextId); } @@ -41,11 +43,13 @@ public void AddGraphQlClient_EmptyApiKey_InConfiguration_ThrowsExceptions() [AutoData] public void AddGraphQlClient_EmptyEndpoint_WithApiKey_ThrowsExceptions(string apiKey) { - Func act = - () => Substitute.For().AddGraphQlClient(options => - { - options.ApiKey = apiKey; - }); + var services = new ServiceCollection(); + services.AddGraphQlClient(options => + { + options.ApiKey = apiKey; + }); + var sp = services.BuildServiceProvider(); + Func act = () => sp.GetRequiredService(); act.Should().Throw() .WithMessage(Resources.Exception_MissingEndpoint); } From 818f8fbf9d4ebf596669418640b78d2e2318a733 Mon Sep 17 00:00:00 2001 From: Jesper Balle Date: Thu, 24 Apr 2025 12:46:36 +0200 Subject: [PATCH 2/2] Support configure in AddGraphQlHandler --- .../SitecoreLayoutClientBuilderExtensions.cs | 11 +++++++++-- .../RequestsFixture.cs | 9 ++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Sitecore.AspNetCore.SDK.LayoutService.Client/Extensions/SitecoreLayoutClientBuilderExtensions.cs b/src/Sitecore.AspNetCore.SDK.LayoutService.Client/Extensions/SitecoreLayoutClientBuilderExtensions.cs index 4c5b2d1..bc5a76f 100644 --- a/src/Sitecore.AspNetCore.SDK.LayoutService.Client/Extensions/SitecoreLayoutClientBuilderExtensions.cs +++ b/src/Sitecore.AspNetCore.SDK.LayoutService.Client/Extensions/SitecoreLayoutClientBuilderExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Sitecore.AspNetCore.SDK.LayoutService.Client.Configuration; using Sitecore.AspNetCore.SDK.LayoutService.Client.Interfaces; using Sitecore.AspNetCore.SDK.LayoutService.Client.Properties; @@ -329,8 +330,14 @@ public static ILayoutRequestHandlerBuilder AddGraph uri ??= new Uri("https://edge-platform.sitecorecloud.io/v1/content/api/graphql/v1"); uri = uri.AddQueryString("sitecoreContextId", contextId)!; - GraphQLHttpClient client = new(uri, new SystemTextJsonSerializer()); - builder.Services.TryAddKeyedSingleton(name, client); + builder.Services.TryAddKeyedSingleton(name, (sp, serviceKey) => + { + var optionsKeyed = sp.GetKeyedService>(serviceKey) ?? sp.GetRequiredService>(); + var clientOptions = optionsKeyed.Value; + clientOptions.EndPoint = uri; + GraphQLHttpClient client = new(clientOptions, new SystemTextJsonSerializer()); + return client; + }); builder.WithDefaultRequestOptions(request => { diff --git a/tests/Sitecore.AspNetCore.SDK.LayoutService.Client.Integration.Tests/RequestsFixture.cs b/tests/Sitecore.AspNetCore.SDK.LayoutService.Client.Integration.Tests/RequestsFixture.cs index 906506e..40f6212 100644 --- a/tests/Sitecore.AspNetCore.SDK.LayoutService.Client.Integration.Tests/RequestsFixture.cs +++ b/tests/Sitecore.AspNetCore.SDK.LayoutService.Client.Integration.Tests/RequestsFixture.cs @@ -6,6 +6,7 @@ using GraphQL.Client.Serializer.SystemTextJson; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using NSubstitute.Extensions; using Sitecore.AspNetCore.SDK.AutoFixture.Attributes; using Sitecore.AspNetCore.SDK.AutoFixture.Mocks; using Sitecore.AspNetCore.SDK.LayoutService.Client.Extensions; @@ -40,13 +41,7 @@ public async Task ContextRequest_Ok(string handlerName, string contextId) }; message.Content.Headers.ContentType = new MediaTypeHeaderValue("application/graphql+json"); result.Responses.Push(message); - ServiceDescriptor gqlClient = services.Single(s => s.ServiceKey?.ToString() == handlerName); - GraphQLHttpClientOptions options = ((GraphQLHttpClient)gqlClient.KeyedImplementationInstance!).Options; - options.HttpMessageHandler = result; - services.RemoveAllKeyed(handlerName); - services.AddKeyedSingleton(handlerName, new GraphQLHttpClient( - options, - new SystemTextJsonSerializer())); + services.Configure(options => options.HttpMessageHandler = result); // Build and grab the sut IServiceProvider provider = services.BuildServiceProvider();