diff --git a/src/HotChocolate/Fusion/src/Abstractions/FusionDirectiveArgumentNames.cs b/src/HotChocolate/Fusion/src/Abstractions/FusionDirectiveArgumentNames.cs index 9b8d03d1d86..7a72116b8c2 100644 --- a/src/HotChocolate/Fusion/src/Abstractions/FusionDirectiveArgumentNames.cs +++ b/src/HotChocolate/Fusion/src/Abstractions/FusionDirectiveArgumentNames.cs @@ -11,9 +11,9 @@ internal static class FusionDirectiveArgumentNames public const string NameArg = "name"; /// - /// Gets the name of the client name argument. + /// Gets the name of the client grouping argument. /// - public const string ClientNameArg = "clientName"; + public const string ClientGroupArg = "group"; /// /// Gets the name of the select argument. @@ -66,7 +66,7 @@ internal static class FusionDirectiveArgumentNames public const string VersionArg = "version"; /// - /// Gets the name of the base address argument. + /// Gets the name of the location argument. /// - public const string BaseAddressArg = "baseAddress"; + public const string LocationArg = "location"; } diff --git a/src/HotChocolate/Fusion/src/Abstractions/FusionEnumValueNames.cs b/src/HotChocolate/Fusion/src/Abstractions/FusionEnumValueNames.cs index 401729d60a5..e080a693590 100644 --- a/src/HotChocolate/Fusion/src/Abstractions/FusionEnumValueNames.cs +++ b/src/HotChocolate/Fusion/src/Abstractions/FusionEnumValueNames.cs @@ -6,9 +6,9 @@ namespace HotChocolate.Fusion; internal static class FusionEnumValueNames { /// - /// Gets the name of the query resolver kind. + /// Gets the name of the fetch resolver kind. /// - public const string Query = "QUERY"; + public const string Fetch = "FETCH"; /// /// Gets the name of the batch resolver kind. @@ -16,12 +16,7 @@ internal static class FusionEnumValueNames public const string Batch = "BATCH"; /// - /// Gets the name of the batch by key resolver kind. + /// Gets the name of the subscribe resolver kind. /// - public const string BatchByKey = "BATCH_BY_KEY"; - - /// - /// Gets the name of the subscription resolver kind. - /// - public const string Subscription = "SUBSCRIPTION"; + public const string Subscribe = "SUBSCRIBE"; } diff --git a/src/HotChocolate/Fusion/src/Abstractions/FusionTypeBaseNames.cs b/src/HotChocolate/Fusion/src/Abstractions/FusionTypeBaseNames.cs index 49c512e1e67..45c995ae664 100644 --- a/src/HotChocolate/Fusion/src/Abstractions/FusionTypeBaseNames.cs +++ b/src/HotChocolate/Fusion/src/Abstractions/FusionTypeBaseNames.cs @@ -36,14 +36,9 @@ internal static class FusionTypeBaseNames public static string ReEncodeIdDirective = "reEncodeId"; /// - /// The base name of the HTTP directive. + /// The base name of the transport directive. /// - public const string HttpDirective = "httpClient"; - - /// - /// The base name of the HTTP directive. - /// - public const string WebSocketDirective = "webSocketClient"; + public const string TransportDirective = "transport"; /// /// The base name of the fusion directive. diff --git a/src/HotChocolate/Fusion/src/Abstractions/FusionTypeNames.cs b/src/HotChocolate/Fusion/src/Abstractions/FusionTypeNames.cs index 0d03afafa8a..59aacea628a 100644 --- a/src/HotChocolate/Fusion/src/Abstractions/FusionTypeNames.cs +++ b/src/HotChocolate/Fusion/src/Abstractions/FusionTypeNames.cs @@ -1,4 +1,3 @@ -using System.Data; using System.Diagnostics.CodeAnalysis; using HotChocolate.Language; using HotChocolate.Utilities; @@ -21,8 +20,7 @@ private FusionTypeNames( string isDirective, string nodeDirective, string reEncodeIdDirective, - string httpDirective, - string webSocketDirective, + string transportDirective, string fusionDirective, string selectionScalar, string selectionSetScalar, @@ -39,8 +37,7 @@ private FusionTypeNames( IsDirective = isDirective; NodeDirective = nodeDirective; ReEncodeIdDirective = reEncodeIdDirective; - HttpDirective = httpDirective; - WebSocketDirective = webSocketDirective; + TransportDirective = transportDirective; FusionDirective = fusionDirective; SelectionScalar = selectionScalar; SelectionSetScalar = selectionSetScalar; @@ -56,8 +53,7 @@ private FusionTypeNames( _fusionDirectives.Add(isDirective); _fusionDirectives.Add(nodeDirective); _fusionDirectives.Add(reEncodeIdDirective); - _fusionDirectives.Add(httpDirective); - _fusionDirectives.Add(webSocketDirective); + _fusionDirectives.Add(transportDirective); _fusionDirectives.Add(fusionDirective); _fusionTypes.Add(selectionScalar); @@ -106,14 +102,9 @@ private FusionTypeNames( /// - /// Gets the name of the http directive. + /// Gets the name of the transport directive. /// - public string HttpDirective { get; } - - /// - /// Gets the name of the http directive. - /// - public string WebSocketDirective { get; } + public string TransportDirective { get; } /// /// Gets the name of the fusion directive. @@ -205,8 +196,7 @@ public static FusionTypeNames Create(string? prefix = null, bool prefixSelf = fa $"{prefix}_{FusionTypeBaseNames.IsDirective}", $"{prefix}_{FusionTypeBaseNames.NodeDirective}", $"{prefix}_{FusionTypeBaseNames.ReEncodeIdDirective}", - $"{prefix}_{FusionTypeBaseNames.HttpDirective}", - $"{prefix}_{FusionTypeBaseNames.WebSocketDirective}", + $"{prefix}_{FusionTypeBaseNames.TransportDirective}", prefixSelf ? $"{prefix}_{FusionTypeBaseNames.FusionDirective}" : FusionTypeBaseNames.FusionDirective, @@ -227,8 +217,7 @@ public static FusionTypeNames Create(string? prefix = null, bool prefixSelf = fa FusionTypeBaseNames.IsDirective, FusionTypeBaseNames.NodeDirective, FusionTypeBaseNames.ReEncodeIdDirective, - FusionTypeBaseNames.HttpDirective, - FusionTypeBaseNames.WebSocketDirective, + FusionTypeBaseNames.TransportDirective, FusionTypeBaseNames.FusionDirective, $"_{FusionTypeBaseNames.Selection}", $"_{FusionTypeBaseNames.SelectionSet}", diff --git a/src/HotChocolate/Fusion/src/Composition/Entities/EntityResolverKind.cs b/src/HotChocolate/Fusion/src/Composition/Entities/EntityResolverKind.cs index f30513f15a2..7cacaf8e755 100644 --- a/src/HotChocolate/Fusion/src/Composition/Entities/EntityResolverKind.cs +++ b/src/HotChocolate/Fusion/src/Composition/Entities/EntityResolverKind.cs @@ -4,6 +4,5 @@ public enum EntityResolverKind { Single = 0, Batch = 1, - BatchWithKey = 2, - Subscription = 3 + Subscribe = 2 } diff --git a/src/HotChocolate/Fusion/src/Composition/FusionTypes.cs b/src/HotChocolate/Fusion/src/Composition/FusionTypes.cs index 51275cefe7e..835b10aa667 100644 --- a/src/HotChocolate/Fusion/src/Composition/FusionTypes.cs +++ b/src/HotChocolate/Fusion/src/Composition/FusionTypes.cs @@ -36,16 +36,22 @@ public FusionTypes(Schema fusionGraph, string? prefix = null, bool prefixSelf = nameof(fusionGraph)); } - if (!_fusionGraph.Types.TryGetType(SpecScalarTypes.Boolean, out var boolean)) + if (!_fusionGraph.Types.TryGetType(SpecScalarTypes.Boolean, out var booleanType)) { - boolean = new ScalarType(SpecScalarTypes.Boolean) { IsSpecScalar = true }; - _fusionGraph.Types.Add(boolean); + booleanType = new ScalarType(SpecScalarTypes.Boolean) { IsSpecScalar = true }; + _fusionGraph.Types.Add(booleanType); } - if (!_fusionGraph.Types.TryGetType(SpecScalarTypes.Int, out var integer)) + if (!_fusionGraph.Types.TryGetType(SpecScalarTypes.Int, out var intType)) { - integer = new ScalarType(SpecScalarTypes.Int) { IsSpecScalar = true }; - _fusionGraph.Types.Add(integer); + intType = new ScalarType(SpecScalarTypes.Int) { IsSpecScalar = true }; + _fusionGraph.Types.Add(intType); + } + + if (!_fusionGraph.Types.TryGetType(SpecScalarTypes.String, out var stringType)) + { + stringType = new ScalarType(SpecScalarTypes.String) { IsSpecScalar = true }; + _fusionGraph.Types.Add(stringType); } Selection = RegisterScalarType(names.SelectionScalar); @@ -76,14 +82,11 @@ public FusionTypes(Schema fusionGraph, string? prefix = null, bool prefixSelf = Fusion = RegisterFusionDirectiveType( names.FusionDirective, TypeName, - boolean, - integer); - HttpClient = RegisterHttpDirectiveType( - names.HttpDirective, - TypeName, - Uri); - WebSocketClient = RegisterWebSocketDirectiveType( - names.WebSocketDirective, + booleanType, + intType); + Transport = RegisterTransportDirectiveType( + names.TransportDirective, + stringType, TypeName, Uri); } @@ -114,9 +117,7 @@ public FusionTypes(Schema fusionGraph, string? prefix = null, bool prefixSelf = public DirectiveType ReEncodeId { get; } - public DirectiveType HttpClient { get; } - - public DirectiveType WebSocketClient { get; } + public DirectiveType Transport { get; } public DirectiveType Fusion { get; } @@ -144,10 +145,9 @@ private InputObjectType RegisterArgumentDefType( private EnumType RegisterResolverKindType(string name) { var resolverKind = new EnumType(name); - resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Query)); + resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Fetch)); resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Batch)); - resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.BatchByKey)); - resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Subscription)); + resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Subscribe)); resolverKind.ContextData.Add(WellKnownContextData.IsFusionType, true); _fusionGraph.Types.Add(resolverKind); return resolverKind; @@ -237,8 +237,7 @@ public Directive CreateResolverDirective( var kindValue = kind switch { EntityResolverKind.Batch => FusionEnumValueNames.Batch, - EntityResolverKind.BatchWithKey => FusionEnumValueNames.BatchByKey, - EntityResolverKind.Subscription => FusionEnumValueNames.Subscription, + EntityResolverKind.Subscribe => FusionEnumValueNames.Subscribe, _ => throw new NotSupportedException() }; @@ -256,12 +255,11 @@ private DirectiveType RegisterResolverDirectiveType( EnumType resolverKind) { var directiveType = new DirectiveType(name); + directiveType.Locations |= DirectiveLocation.Object; directiveType.Arguments.Add(new InputField(SelectArg, new NonNullType(selectionSet))); directiveType.Arguments.Add(new InputField(SubgraphArg, new NonNullType(typeName))); - directiveType.Arguments.Add( - new InputField(ArgumentsArg, new ListType(new NonNullType(argumentDef)))); + directiveType.Arguments.Add(new InputField(ArgumentsArg, new ListType(new NonNullType(argumentDef)))); directiveType.Arguments.Add(new InputField(KindArg, resolverKind)); - directiveType.Locations |= DirectiveLocation.Object; directiveType.ContextData.Add(WellKnownContextData.IsFusionType, true); _fusionGraph.DirectiveTypes.Add(directiveType); return directiveType; @@ -279,11 +277,25 @@ public Directive CreateSourceDirective(string subgraphName, string? originalName private DirectiveType RegisterSourceDirectiveType(string name, ScalarType typeName) { - var directiveType = new DirectiveType(name); - directiveType.Locations = DirectiveLocation.FieldDefinition; - directiveType.Arguments.Add(new InputField(SubgraphArg, new NonNullType(typeName))); - directiveType.Arguments.Add(new InputField(NameArg, typeName)); - directiveType.ContextData.Add(WellKnownContextData.IsFusionType, true); + var directiveType = new DirectiveType(name) + { + Locations = DirectiveLocation.Object | + DirectiveLocation.FieldDefinition | + DirectiveLocation.Enum | + DirectiveLocation.EnumValue | + DirectiveLocation.InputObject | + DirectiveLocation.InputFieldDefinition | + DirectiveLocation.Scalar, + Arguments = + { + new InputField(SubgraphArg, new NonNullType(typeName)), + new InputField(NameArg, typeName) + }, + ContextData = + { + [WellKnownContextData.IsFusionType] = true + } + }; _fusionGraph.DirectiveTypes.Add(directiveType); return directiveType; } @@ -310,59 +322,50 @@ private DirectiveType RegisterNodeDirectiveType(string name, ScalarType typeName return directiveType; } - public Directive CreateHttpDirective(string subgraphName, string? clientName, Uri baseAddress) + public Directive CreateHttpDirective(string subgraphName, string? clientName, Uri location) => clientName is null ? new Directive( - HttpClient, + Transport, new Argument(SubgraphArg, subgraphName), - new Argument(BaseAddressArg, baseAddress.ToString())) + new Argument(LocationArg, location.ToString()), + new Argument(KindArg, "HTTP")) : new Directive( - HttpClient, + Transport, new Argument(SubgraphArg, subgraphName), - new Argument(ClientNameArg, clientName), - new Argument(BaseAddressArg, baseAddress.ToString())); + new Argument(ClientGroupArg, clientName), + new Argument(LocationArg, location.ToString()), + new Argument(KindArg, "HTTP")); - private DirectiveType RegisterHttpDirectiveType( + private DirectiveType RegisterTransportDirectiveType( string name, + ScalarType stringType, ScalarType typeName, ScalarType uri) { var directiveType = new DirectiveType(name); directiveType.Locations = DirectiveLocation.FieldDefinition; directiveType.Arguments.Add(new InputField(SubgraphArg, new NonNullType(typeName))); - directiveType.Arguments.Add(new InputField(ClientNameArg, typeName)); - directiveType.Arguments.Add(new InputField(BaseAddressArg, uri)); + directiveType.Arguments.Add(new InputField(ClientGroupArg, typeName)); + directiveType.Arguments.Add(new InputField(LocationArg, uri)); + directiveType.Arguments.Add(new InputField(KindArg, new NonNullType(stringType))); directiveType.ContextData.Add(WellKnownContextData.IsFusionType, true); _fusionGraph.DirectiveTypes.Add(directiveType); return directiveType; } - public Directive CreateWebSocketDirective(string subgraphName, string? clientName, Uri baseAddress) + public Directive CreateWebSocketDirective(string subgraphName, string? clientName, Uri location) => clientName is null ? new Directive( - WebSocketClient, + Transport, new Argument(SubgraphArg, subgraphName), - new Argument(BaseAddressArg, baseAddress.ToString())) + new Argument(LocationArg, location.ToString()), + new Argument(KindArg, "WebSocket")) : new Directive( - WebSocketClient, + Transport, new Argument(SubgraphArg, subgraphName), - new Argument(ClientNameArg, clientName), - new Argument(BaseAddressArg, baseAddress.ToString())); - - private DirectiveType RegisterWebSocketDirectiveType( - string name, - ScalarType typeName, - ScalarType uri) - { - var directiveType = new DirectiveType(name); - directiveType.Locations = DirectiveLocation.FieldDefinition; - directiveType.Arguments.Add(new InputField(SubgraphArg, new NonNullType(typeName))); - directiveType.Arguments.Add(new InputField(ClientNameArg, typeName)); - directiveType.Arguments.Add(new InputField(BaseAddressArg, uri)); - directiveType.ContextData.Add(WellKnownContextData.IsFusionType, true); - _fusionGraph.DirectiveTypes.Add(directiveType); - return directiveType; - } + new Argument(ClientGroupArg, clientName), + new Argument(LocationArg, location.ToString()), + new Argument(KindArg, "WebSocket")); private DirectiveType RegisterFusionDirectiveType( string name, diff --git a/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/NodeEntityEnricher.cs b/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/NodeEntityEnricher.cs index 023e470d5ab..09f16b432ed 100644 --- a/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/NodeEntityEnricher.cs +++ b/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/NodeEntityEnricher.cs @@ -142,7 +142,7 @@ private static void ResolveWithNodes( // Create a new EntityResolver for the entity var resolver = new EntityResolver( - EntityResolverKind.BatchWithKey, + EntityResolverKind.Batch, selectionSet, sourceType.Name, sourceSchema.Name); diff --git a/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/PatternEntityEnricher.cs b/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/PatternEntityEnricher.cs index 066e58b1f57..a0d1090e045 100644 --- a/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/PatternEntityEnricher.cs +++ b/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/PatternEntityEnricher.cs @@ -213,7 +213,7 @@ private static void TryRegisterBatchEntityResolver( // Create a new EntityResolver for the entity var resolver = new EntityResolver( - EntityResolverKind.BatchWithKey, + EntityResolverKind.Batch, selectionSet, entityType.Name, schema.Name); diff --git a/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/RefResolverEntityEnricher.cs b/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/RefResolverEntityEnricher.cs index fac4770747e..5c7dd7cc316 100644 --- a/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/RefResolverEntityEnricher.cs +++ b/src/HotChocolate/Fusion/src/Composition/Pipeline/Enrichers/RefResolverEntityEnricher.cs @@ -54,7 +54,7 @@ public ValueTask EnrichAsync( // Create a new EntityResolver for the entity var resolver = new EntityResolver( - EntityResolverKind.BatchWithKey, + EntityResolverKind.Batch, selectionSet, type.Name, schema.Name); @@ -92,6 +92,7 @@ private static void TryRegisterEntityResolver( if ((entityResolverField.Type == entityType || (entityResolverField.Type.Kind is TypeKind.NonNull && entityResolverField.Type.InnerType() == entityType)) && + entityResolverField.Arguments.Count > 0 && entityResolverField.Arguments.All(t => t.ContainsIsDirective())) { var arguments = new List(); diff --git a/src/HotChocolate/Fusion/src/Composition/Pipeline/MergeSubscriptionTypeMiddleware.cs b/src/HotChocolate/Fusion/src/Composition/Pipeline/MergeSubscriptionTypeMiddleware.cs index 899e7bcf6ff..235817b5922 100644 --- a/src/HotChocolate/Fusion/src/Composition/Pipeline/MergeSubscriptionTypeMiddleware.cs +++ b/src/HotChocolate/Fusion/src/Composition/Pipeline/MergeSubscriptionTypeMiddleware.cs @@ -108,7 +108,7 @@ private static Directive CreateResolverDirective( subgraphName, selectionSet, arguments, - EntityResolverKind.Subscription); + EntityResolverKind.Subscribe); private static Directive CreateVariableDirective( CompositionContext context, diff --git a/src/HotChocolate/Fusion/src/Composition/Pipeline/RemoveFusionTypesMiddleware.cs b/src/HotChocolate/Fusion/src/Composition/Pipeline/RemoveFusionTypesMiddleware.cs index a4f65bc9c61..2b6ba5a0389 100644 --- a/src/HotChocolate/Fusion/src/Composition/Pipeline/RemoveFusionTypesMiddleware.cs +++ b/src/HotChocolate/Fusion/src/Composition/Pipeline/RemoveFusionTypesMiddleware.cs @@ -23,8 +23,7 @@ public ValueTask InvokeAsync(CompositionContext context, MergeDelegate next) context.FusionGraph.DirectiveTypes.Remove(context.FusionTypes.Source); context.FusionGraph.DirectiveTypes.Remove(context.FusionTypes.Node); context.FusionGraph.DirectiveTypes.Remove(context.FusionTypes.ReEncodeId); - context.FusionGraph.DirectiveTypes.Remove(context.FusionTypes.HttpClient); - context.FusionGraph.DirectiveTypes.Remove(context.FusionTypes.WebSocketClient); + context.FusionGraph.DirectiveTypes.Remove(context.FusionTypes.Transport); context.FusionGraph.DirectiveTypes.Remove(context.FusionTypes.Fusion); return next(context); diff --git a/src/HotChocolate/Fusion/src/Core/Metadata/ConfigurationRewriter.cs b/src/HotChocolate/Fusion/src/Core/Metadata/ConfigurationRewriter.cs index 5249bda4367..74ef6e17359 100644 --- a/src/HotChocolate/Fusion/src/Core/Metadata/ConfigurationRewriter.cs +++ b/src/HotChocolate/Fusion/src/Core/Metadata/ConfigurationRewriter.cs @@ -38,9 +38,9 @@ public virtual async ValueTask RewriteAsync( if (!ReferenceEquals(rewritten, client)) { var arguments = new List(); - arguments.Add(new ArgumentNode(ClientNameArg, rewritten.ClientName)); + arguments.Add(new ArgumentNode(ClientGroupArg, rewritten.ClientName)); arguments.Add(new ArgumentNode(SubgraphArg, rewritten.SubgraphName)); - arguments.Add(new ArgumentNode(BaseAddressArg, rewritten.EndpointUri.ToString())); + arguments.Add(new ArgumentNode(LocationArg, rewritten.EndpointUri.ToString())); Replace(client.SyntaxNode!, client.SyntaxNode!.WithArguments(arguments)); } } @@ -52,9 +52,9 @@ public virtual async ValueTask RewriteAsync( if (!ReferenceEquals(rewritten, client)) { var arguments = new List(); - arguments.Add(new ArgumentNode(ClientNameArg, rewritten.ClientName)); + arguments.Add(new ArgumentNode(ClientGroupArg, rewritten.ClientName)); arguments.Add(new ArgumentNode(SubgraphArg, rewritten.SubgraphName)); - arguments.Add(new ArgumentNode(BaseAddressArg, rewritten.EndpointUri.ToString())); + arguments.Add(new ArgumentNode(LocationArg, rewritten.EndpointUri.ToString())); Replace(client.SyntaxNode!, client.SyntaxNode!.WithArguments(arguments)); } } diff --git a/src/HotChocolate/Fusion/src/Core/Metadata/FusionGraphConfigurationReader.cs b/src/HotChocolate/Fusion/src/Core/Metadata/FusionGraphConfigurationReader.cs index ceec5c00488..5694e92fbfb 100644 --- a/src/HotChocolate/Fusion/src/Core/Metadata/FusionGraphConfigurationReader.cs +++ b/src/HotChocolate/Fusion/src/Core/Metadata/FusionGraphConfigurationReader.cs @@ -2,7 +2,6 @@ using HotChocolate.Language.Visitors; using HotChocolate.Types.Introspection; using HotChocolate.Utilities; -using Microsoft.Extensions.DependencyInjection; using static HotChocolate.Fusion.FusionDirectiveArgumentNames; using static HotChocolate.Fusion.FusionResources; using static HotChocolate.Fusion.Utilities.ThrowHelper; @@ -138,31 +137,38 @@ private IReadOnlyList ReadHttpClientConfigs( foreach (var directiveNode in directiveNodes) { - if (directiveNode.Name.Value.EqualsOrdinal(typeNames.HttpDirective)) + if (!directiveNode.Name.Value.EqualsOrdinal(typeNames.TransportDirective)) { - configs.Add(ReadHttpClientConfig(typeNames, directiveNode)); + continue; + } + + var config = TryReadHttpClientConfig(typeNames, directiveNode); + if (config is not null) + { + configs.Add(config); } } return configs; } - private HttpClientConfiguration ReadHttpClientConfig( + private HttpClientConfiguration? TryReadHttpClientConfig( FusionTypeNames typeNames, DirectiveNode directiveNode) { - AssertName(directiveNode, typeNames.HttpDirective); - AssertArguments(directiveNode, OptionalArgs, SubgraphArg, BaseAddressArg); + AssertName(directiveNode, typeNames.TransportDirective); + AssertArguments(directiveNode, OptionalArgs, SubgraphArg, LocationArg, KindArg); string name = default!; string subgraph = default!; string baseAddress = default!; + string kind = default!; foreach (var argument in directiveNode.Arguments) { switch (argument.Name.Value) { - case ClientNameArg: + case ClientGroupArg: name = Expect(argument.Value).Value; break; @@ -170,11 +176,20 @@ private HttpClientConfiguration ReadHttpClientConfig( subgraph = Expect(argument.Value).Value; break; - case BaseAddressArg: + case LocationArg: baseAddress = Expect(argument.Value).Value; break; + + case KindArg: + kind = Expect(argument.Value).Value; + break; } } + + if (!kind.EqualsOrdinal("HTTP")) + { + return null; + } if (string.IsNullOrEmpty(name)) { @@ -185,7 +200,7 @@ private HttpClientConfiguration ReadHttpClientConfig( static void OptionalArgs(HashSet assert) { - assert.Remove(ClientNameArg); + assert.Remove(ClientGroupArg); } } @@ -197,31 +212,38 @@ private IReadOnlyList ReadWebSocketClientConfigs( foreach (var directiveNode in directiveNodes) { - if (directiveNode.Name.Value.EqualsOrdinal(typeNames.WebSocketDirective)) + if (!directiveNode.Name.Value.EqualsOrdinal(typeNames.TransportDirective)) { - configs.Add(ReadWebSocketClientConfig(typeNames, directiveNode)); + continue; + } + + var config = TryReadWebSocketClientConfig(typeNames, directiveNode); + if (config is not null) + { + configs.Add(config); } } return configs; } - private WebSocketClientConfiguration ReadWebSocketClientConfig( + private WebSocketClientConfiguration? TryReadWebSocketClientConfig( FusionTypeNames typeNames, DirectiveNode directiveNode) { - AssertName(directiveNode, typeNames.WebSocketDirective); - AssertArguments(directiveNode, OptionalArgs, SubgraphArg, BaseAddressArg); + AssertName(directiveNode, typeNames.TransportDirective); + AssertArguments(directiveNode, OptionalArgs, SubgraphArg, LocationArg, KindArg); string name = default!; string subgraph = default!; string baseAddress = default!; + string kind = default!; foreach (var argument in directiveNode.Arguments) { switch (argument.Name.Value) { - case ClientNameArg: + case ClientGroupArg: name = Expect(argument.Value).Value; break; @@ -229,12 +251,21 @@ private WebSocketClientConfiguration ReadWebSocketClientConfig( subgraph = Expect(argument.Value).Value; break; - case BaseAddressArg: + case LocationArg: baseAddress = Expect(argument.Value).Value; break; + + case KindArg: + kind = Expect(argument.Value).Value; + break; } } + if (!kind.EqualsOrdinal("WebSocket")) + { + return null; + } + if (string.IsNullOrEmpty(name)) { name = subgraph; @@ -244,7 +275,7 @@ private WebSocketClientConfiguration ReadWebSocketClientConfig( static void OptionalArgs(HashSet assert) { - assert.Remove(ClientNameArg); + assert.Remove(ClientGroupArg); } } @@ -453,10 +484,9 @@ private ResolverDefinition ReadResolverDefinition( case KindArg: kind = Expect(argument.Value).Value switch { - FusionEnumValueNames.Query => ResolverKind.Query, + FusionEnumValueNames.Fetch => ResolverKind.Query, FusionEnumValueNames.Batch => ResolverKind.Batch, - FusionEnumValueNames.BatchByKey => ResolverKind.BatchByKey, - FusionEnumValueNames.Subscription => ResolverKind.Subscription, + FusionEnumValueNames.Subscribe => ResolverKind.Subscribe, _ => throw new InvalidOperationException( FusionGraphConfigurationReader_ReadResolverDefinition_InvalidKindValue) }; diff --git a/src/HotChocolate/Fusion/src/Core/Metadata/ResolverKind.cs b/src/HotChocolate/Fusion/src/Core/Metadata/ResolverKind.cs index c378e749b8c..f266246f99b 100644 --- a/src/HotChocolate/Fusion/src/Core/Metadata/ResolverKind.cs +++ b/src/HotChocolate/Fusion/src/Core/Metadata/ResolverKind.cs @@ -4,6 +4,5 @@ internal enum ResolverKind { Query, Batch, - BatchByKey, - Subscription, + Subscribe, } diff --git a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionNodeBuilderMiddleware.cs b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionNodeBuilderMiddleware.cs index d2f1cc0b1ee..cec7afd90e4 100644 --- a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionNodeBuilderMiddleware.cs +++ b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionNodeBuilderMiddleware.cs @@ -7,7 +7,6 @@ using HotChocolate.Types; using HotChocolate.Utilities; using static HotChocolate.Fusion.FusionResources; -using static HotChocolate.Fusion.Metadata.ResolverKind; namespace HotChocolate.Fusion.Planning.Pipeline; @@ -42,14 +41,14 @@ public void Invoke(QueryPlanContext context, QueryPlanDelegate next) continue; } - if (selectionStep.Resolver?.Kind == BatchByKey) + if (selectionStep.Resolver?.Kind == ResolverKind.Batch) { var resolve = CreateResolveByKeyBatchNode(context, selectionStep); context.RegisterNode(resolve, selectionStep); } else if (selectionStep.Resolver is null && selectionStep.RootSelections.Count == 1 && - selectionStep.RootSelections[0].Resolver?.Kind is Subscription) + selectionStep.RootSelections[0].Resolver?.Kind is ResolverKind.Subscribe) { var resolve = CreateSubscribeNode(context, selectionStep); context.RegisterNode(resolve, selectionStep); diff --git a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionStepDiscoveryMiddleware.cs b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionStepDiscoveryMiddleware.cs index 0667891450c..70f1fb7e506 100644 --- a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionStepDiscoveryMiddleware.cs +++ b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/ExecutionStepDiscoveryMiddleware.cs @@ -602,7 +602,7 @@ private static bool TryGetResolver( { if (preference is PreferredResolverKind.Subscription) { - if (current.Kind is ResolverKind.Subscription) + if (current.Kind is ResolverKind.Subscribe) { resolver = current; return true; @@ -616,15 +616,6 @@ private static bool TryGetResolver( { case ResolverKind.Batch: resolver = current; - - if (preference is PreferredResolverKind.Batch) - { - return true; - } - break; - - case ResolverKind.BatchByKey: - resolver = current; break; default: diff --git a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/FieldRequirementsPlannerMiddleware.cs b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/FieldRequirementsPlannerMiddleware.cs index 7e486c3d6ea..30ad56aa42e 100644 --- a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/FieldRequirementsPlannerMiddleware.cs +++ b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/FieldRequirementsPlannerMiddleware.cs @@ -250,8 +250,7 @@ private static ResolverDefinition SelectResolver( if (requirements > resolver.Requires.Count || selectedResolver is null || (selectedResolver.Requires.Count == resolver.Requires.Count && selectedResolver.Kind == ResolverKind.Query && - (resolver.Kind == ResolverKind.Batch || - resolver.Kind == ResolverKind.BatchByKey))) + resolver.Kind == ResolverKind.Batch)) { requirements = resolver.Requires.Count; selectedResolver = resolver; diff --git a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/RequirementsPlannerMiddleware.cs b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/RequirementsPlannerMiddleware.cs index e3a5a012625..6d3b0bd53ec 100644 --- a/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/RequirementsPlannerMiddleware.cs +++ b/src/HotChocolate/Fusion/src/Core/Planning/Pipeline/RequirementsPlannerMiddleware.cs @@ -167,7 +167,7 @@ currentStep.ParentSelection is { } parent && // if we do by key batching the current execution step must // re-export its requirements so we know where entities belong to. - if (currentStep.Resolver.Kind is ResolverKind.BatchByKey) + if (currentStep.Resolver.Kind is ResolverKind.Batch) { foreach (var variable in step.SelectionSetTypeMetadata.Variables) { diff --git a/src/HotChocolate/Fusion/test/Abstractions.Tests/FusionTypeNamesTests.cs b/src/HotChocolate/Fusion/test/Abstractions.Tests/FusionTypeNamesTests.cs index c6a97d96b14..e23e52e37bd 100644 --- a/src/HotChocolate/Fusion/test/Abstractions.Tests/FusionTypeNamesTests.cs +++ b/src/HotChocolate/Fusion/test/Abstractions.Tests/FusionTypeNamesTests.cs @@ -16,7 +16,7 @@ public void Create_DefaultPrefix_ReturnsDefaultNames() Assert.Equal("resolver", fusionTypeNames.ResolverDirective); Assert.Equal("source", fusionTypeNames.SourceDirective); Assert.Equal("is", fusionTypeNames.IsDirective); - Assert.Equal("httpClient", fusionTypeNames.HttpDirective); + Assert.Equal("transport", fusionTypeNames.TransportDirective); Assert.Equal("fusion", fusionTypeNames.FusionDirective); Assert.Equal("_Selection", fusionTypeNames.SelectionScalar); Assert.Equal("_SelectionSet", fusionTypeNames.SelectionSetScalar); @@ -37,7 +37,7 @@ public void Create_CustomPrefix_ReturnsCustomNames() Assert.Equal("MyPrefix_resolver", fusionTypeNames.ResolverDirective); Assert.Equal("MyPrefix_source", fusionTypeNames.SourceDirective); Assert.Equal("MyPrefix_is", fusionTypeNames.IsDirective); - Assert.Equal("MyPrefix_httpClient", fusionTypeNames.HttpDirective); + Assert.Equal("MyPrefix_transport", fusionTypeNames.TransportDirective); Assert.Equal("MyPrefix_fusion", fusionTypeNames.FusionDirective); Assert.Equal("MyPrefix_Selection", fusionTypeNames.SelectionScalar); Assert.Equal("MyPrefix_SelectionSet", fusionTypeNames.SelectionSetScalar); @@ -60,7 +60,7 @@ public void From_SchemaWithFusionDirective_ReturnsCustomNames() Assert.Equal("MyPrefix_resolver", fusionTypeNames.ResolverDirective); Assert.Equal("MyPrefix_source", fusionTypeNames.SourceDirective); Assert.Equal("MyPrefix_is", fusionTypeNames.IsDirective); - Assert.Equal("MyPrefix_httpClient", fusionTypeNames.HttpDirective); + Assert.Equal("MyPrefix_transport", fusionTypeNames.TransportDirective); Assert.Equal("fusion", fusionTypeNames.FusionDirective); Assert.Equal("MyPrefix_Selection", fusionTypeNames.SelectionScalar); Assert.Equal("MyPrefix_SelectionSet", fusionTypeNames.SelectionSetScalar); @@ -83,7 +83,7 @@ public void From_SchemaWithPrefixedFusionDirective_ReturnsCustomNames() Assert.Equal("MyOtherPrefix_resolver", fusionTypeNames.ResolverDirective); Assert.Equal("MyOtherPrefix_source", fusionTypeNames.SourceDirective); Assert.Equal("MyOtherPrefix_is", fusionTypeNames.IsDirective); - Assert.Equal("MyOtherPrefix_httpClient", fusionTypeNames.HttpDirective); + Assert.Equal("MyOtherPrefix_transport", fusionTypeNames.TransportDirective); Assert.Equal("MyOtherPrefix_fusion", fusionTypeNames.FusionDirective); Assert.Equal("MyOtherPrefix_Selection", fusionTypeNames.SelectionScalar); Assert.Equal("MyOtherPrefix_SelectionSet", fusionTypeNames.SelectionSetScalar); diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/ComposeCommandTests.cs b/src/HotChocolate/Fusion/test/CommandLine.Tests/ComposeCommandTests.cs index 8a4d8270130..652cbfb4053 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/ComposeCommandTests.cs +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/ComposeCommandTests.cs @@ -87,8 +87,7 @@ await PackageHelper.CreateSubgraphPackageAsync( var packageFile = CreateTempFile(Extensions.FusionPackage); var app = App.CreateBuilder().Build(); - await app.InvokeAsync( - new[] { "compose", "-p", packageFile, "-s", accountSubgraphPackageFile }); + await app.InvokeAsync(new[] { "compose", "-p", packageFile, "-s", accountSubgraphPackageFile }); // act app = App.CreateBuilder().Build(); diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.snap b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.snap index cf7e84b9142..e555351f05c 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.snap +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph.snap @@ -9,6 +9,7 @@ type Query { userById(id: ID!): User users: [User!]! usersById(ids: [ID!]!): [User!]! + viewer: Viewer! } type Mutation { @@ -19,6 +20,10 @@ type AddUserPayload { user: User } +type SomeData { + accountValue: String! +} + type User implements Node { birthdate: Date! id: ID! @@ -26,6 +31,11 @@ type User implements Node { username: String! } +type Viewer { + data: SomeData! + user: User +} + interface Node { id: ID! } @@ -45,7 +55,7 @@ scalar DateTime Fusion Graph Document --------------- -schema @fusion(version: 1) @httpClient(subgraph: "Accounts", clientName: "Fusion", baseAddress: "http:\/\/localhost:5000\/graphql") @webSocketClient(subgraph: "Accounts", clientName: "Fusion", baseAddress: "ws:\/\/localhost:5000\/graphql") { +schema @fusion(version: 1) @transport(subgraph: "Accounts", group: "Fusion", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") @transport(subgraph: "Accounts", group: "Fusion", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation } @@ -54,6 +64,7 @@ type Query { userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -64,13 +75,22 @@ type AddUserPayload { user: User @source(subgraph: "Accounts") } -type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { +type SomeData { + accountValue: String! @source(subgraph: "Accounts") +} + +type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @source(subgraph: "Accounts") name: String! @source(subgraph: "Accounts") username: String! @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! @source(subgraph: "Accounts") + user: User @source(subgraph: "Accounts") +} + interface Node { id: ID! } @@ -92,7 +112,7 @@ Accounts Subgraph Configuration --------------- { "Name": "Accounts", - "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}", + "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}", "Extensions": [ "extend type Query {\n userById(id: ID!\n @is(field: \"id\")): User!\n usersById(ids: [ID!]!\n @is(field: \"id\")): [User!]!\n}" ], diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.snap b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.snap index 7137ff0e178..6a6a224cbae 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.snap +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/ComposeCommandTests.Compose_Fusion_Graph_Append_Subgraph.snap @@ -14,6 +14,7 @@ type Query { userById(id: ID!): User users: [User!]! usersById(ids: [ID!]!): [User!]! + viewer: Viewer! } type Mutation { @@ -45,6 +46,11 @@ type Review implements Node { product: Product! } +type SomeData { + accountValue: String! + reviewsValue: String! +} + type User implements Node { birthdate: Date! id: ID! @@ -53,6 +59,12 @@ type User implements Node { username: String! } +type Viewer { + data: SomeData! + latestReview: Review + user: User +} + interface Node { id: ID! } @@ -80,7 +92,7 @@ scalar DateTime Fusion Graph Document --------------- -schema @fusion(version: 1) @httpClient(subgraph: "Accounts", clientName: "Fusion", baseAddress: "http:\/\/localhost:5000\/graphql") @webSocketClient(subgraph: "Accounts", clientName: "Fusion", baseAddress: "ws:\/\/localhost:5000\/graphql") @httpClient(subgraph: "Reviews2", clientName: "Fusion", baseAddress: "http:\/\/localhost:5000\/graphql") @webSocketClient(subgraph: "Reviews2", clientName: "Fusion", baseAddress: "ws:\/\/localhost:5000\/graphql") { +schema @fusion(version: 1) @transport(subgraph: "Accounts", group: "Fusion", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") @transport(subgraph: "Accounts", group: "Fusion", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @transport(subgraph: "Reviews2", group: "Fusion", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") @transport(subgraph: "Reviews2", group: "Fusion", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -94,6 +106,7 @@ type Query { userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! @resolver(subgraph: "Accounts", select: "{ viewer }") @resolver(subgraph: "Reviews2", select: "{ viewer }") } type Mutation { @@ -102,7 +115,7 @@ type Mutation { } type Subscription { - onNewReview: Review! @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + onNewReview: Review! @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -118,14 +131,19 @@ type Product @variable(subgraph: "Reviews2", name: "Product_id", select: "id") @ reviews: [Review!]! @source(subgraph: "Reviews2") } -type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { +type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @source(subgraph: "Reviews2") id: ID! @source(subgraph: "Reviews2") product: Product! @source(subgraph: "Reviews2") } -type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews2", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { +type SomeData { + accountValue: String! @source(subgraph: "Accounts") + reviewsValue: String! @source(subgraph: "Reviews2") +} + +type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews2", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @source(subgraph: "Accounts") @source(subgraph: "Reviews2") name: String! @source(subgraph: "Accounts") @source(subgraph: "Reviews2") @@ -133,6 +151,12 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", selec username: String! @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! @source(subgraph: "Accounts") @source(subgraph: "Reviews2") + latestReview: Review @source(subgraph: "Reviews2") + user: User @source(subgraph: "Accounts") +} + interface Node { id: ID! } @@ -162,7 +186,7 @@ Accounts Subgraph Configuration --------------- { "Name": "Accounts", - "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}", + "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}", "Extensions": [ "extend type Query {\n userById(id: ID!\n @is(field: \"id\")): User!\n usersById(ids: [ID!]!\n @is(field: \"id\")): [User!]!\n}" ], @@ -183,7 +207,7 @@ Reviews2 Subgraph Configuration --------------- { "Name": "Reviews2", - "Schema": "schema {\n query: Query\n mutation: ReviewsMutation\n subscription: ReviewsSubscription\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n reviews: [Review!]!\n reviewById(id: ID!): Review\n authorById(id: ID!): User\n productById(id: ID!): Product\n reviewOrAuthor: ReviewOrAuthor!\n}\n\ntype ReviewsMutation {\n addReview(input: AddReviewInput!): AddReviewPayload!\n}\n\ntype ReviewsSubscription {\n onNewReview: Review!\n}\n\ntype User implements Node {\n reviews: [Review!]!\n id: ID!\n name: String!\n}\n\ntype Review implements Node {\n id: ID!\n author: User!\n product: Product!\n body: String!\n}\n\ntype Product {\n reviews: [Review!]!\n id: ID!\n}\n\nunion ReviewOrAuthor = User | Review\n\ninput AddReviewInput {\n body: String!\n authorId: Int!\n upc: Int!\n}\n\ntype AddReviewPayload {\n review: Review\n}", + "Schema": "schema {\n query: Query\n mutation: ReviewsMutation\n subscription: ReviewsSubscription\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n reviews: [Review!]!\n reviewById(id: ID!): Review\n authorById(id: ID!): User\n productById(id: ID!): Product\n reviewOrAuthor: ReviewOrAuthor!\n viewer: Viewer!\n}\n\ntype ReviewsMutation {\n addReview(input: AddReviewInput!): AddReviewPayload!\n}\n\ntype ReviewsSubscription {\n onNewReview: Review!\n}\n\ntype User implements Node {\n reviews: [Review!]!\n id: ID!\n name: String!\n}\n\ntype Review implements Node {\n id: ID!\n author: User!\n product: Product!\n body: String!\n}\n\ntype Product {\n reviews: [Review!]!\n id: ID!\n}\n\nunion ReviewOrAuthor = User | Review\n\ntype Viewer {\n latestReview: Review\n data: SomeData!\n}\n\ntype SomeData {\n reviewsValue: String!\n}\n\ninput AddReviewInput {\n body: String!\n authorId: Int!\n upc: Int!\n}\n\ntype AddReviewPayload {\n review: Review\n}", "Extensions": [ "extend type Query {\n authorById(id: ID!\n @is(field: \"id\")): Author\n productById(id: ID!\n @is(field: \"id\")): Product\n}\n\nschema\n @rename(coordinate: \"Query.authorById\", newName: \"userById\")\n @rename(coordinate: \"Author\", newName: \"User\") {\n\n}" ], diff --git a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap index af5d6dc4c3f..8a978ed19fb 100644 --- a/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap +++ b/src/HotChocolate/Fusion/test/CommandLine.Tests/__snapshots__/PackageHelperTests.Create_Subgraph_Package.snap @@ -1,6 +1,6 @@ { "Name": "Accounts", - "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}", + "Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}", "Extensions": [ "extend type Query {\n userById(id: ID!\n @is(field: \"id\")): User!\n usersById(ids: [ID!]!\n @is(field: \"id\")): [User!]!\n}" ], diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/DataTypes.cs b/src/HotChocolate/Fusion/test/Composition.Tests/DataTypes.cs new file mode 100644 index 00000000000..5efd6dd2ca9 --- /dev/null +++ b/src/HotChocolate/Fusion/test/Composition.Tests/DataTypes.cs @@ -0,0 +1,68 @@ +using CookieCrumble; +using HotChocolate.Fusion.Shared; +using HotChocolate.Skimmed.Serialization; +using Xunit.Abstractions; + +namespace HotChocolate.Fusion.Composition; + +public class DataTypes(ITestOutputHelper output) +{ + private readonly Func _logFactory = () => new TestCompositionLog(output); + + [Fact] + public async Task Compose_Schema_With_Data_Only() + { + // arrange + var configA = new SubgraphConfiguration( + "A", + """ + schema { + query: Query + } + + type Query { + someData: SomeData + } + + type SomeData { + other: OtherData + } + + type OtherData { + a: String + } + """, + Array.Empty(), + new[] { new HttpClientConfiguration(new Uri("https://localhost:5001/graphql")) }); + + var configB = new SubgraphConfiguration( + "B", + """ + schema { + query: Query + } + + type Query { + someData: SomeData + } + + type SomeData { + other: OtherData + } + + type OtherData { + b: String + } + """, + Array.Empty(), + new[] { new HttpClientConfiguration(new Uri("https://localhost:5002/graphql")) }); + + // act + var composer = new FusionGraphComposer(logFactory: _logFactory); + var fusionConfig = await composer.ComposeAsync(new[] { configA, configB }); + + SchemaFormatter + .FormatAsString(fusionConfig) + .MatchSnapshot(extension: ".graphql"); + } +} \ No newline at end of file diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/DemoIntegrationTests.cs b/src/HotChocolate/Fusion/test/Composition.Tests/DemoIntegrationTests.cs index a2b4ba90b5a..badbe98c133 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/DemoIntegrationTests.cs +++ b/src/HotChocolate/Fusion/test/Composition.Tests/DemoIntegrationTests.cs @@ -7,14 +7,9 @@ namespace HotChocolate.Fusion.Composition; -public sealed class DemoIntegrationTests +public sealed class DemoIntegrationTests(ITestOutputHelper output) { - private readonly Func _logFactory; - - public DemoIntegrationTests(ITestOutputHelper output) - { - _logFactory = () => new TestCompositionLog(output); - } + private readonly Func _logFactory = () => new TestCompositionLog(output); [Fact] public async Task Accounts_And_Reviews() diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DataTypes.Compose_Schema_With_Data_Only.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DataTypes.Compose_Schema_With_Data_Only.graphql new file mode 100644 index 00000000000..7f3ea327522 --- /dev/null +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DataTypes.Compose_Schema_With_Data_Only.graphql @@ -0,0 +1,25 @@ +schema + @fusion(version: 1) + @transport(subgraph: "A", location: "https:\/\/localhost:5001\/graphql", kind: "HTTP") + @transport(subgraph: "B", location: "https:\/\/localhost:5002\/graphql", kind: "HTTP") { + query: Query +} + +type Query { + someData: SomeData + @resolver(subgraph: "A", select: "{ someData }") + @resolver(subgraph: "B", select: "{ someData }") +} + +type OtherData { + a: String + @source(subgraph: "A") + b: String + @source(subgraph: "B") +} + +type SomeData { + other: OtherData + @source(subgraph: "A") + @source(subgraph: "B") +} \ No newline at end of file diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql index f0397d87a76..51b4658d478 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -30,6 +30,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -43,7 +45,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -70,7 +72,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -81,18 +83,23 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type User implements Node @source(subgraph: "Reviews", name: "Author") @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -107,6 +114,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql index 30757c74e7a..2fbedca906a 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews2_Products_With_Nodes.graphql @@ -1,11 +1,11 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -56,6 +56,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") + @resolver(subgraph: "Reviews2", select: "{ viewer }") } type Mutation { @@ -72,7 +75,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -93,7 +96,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -133,7 +136,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -145,10 +148,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -162,14 +169,14 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews2", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -184,6 +191,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + @source(subgraph: "Reviews2") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql index 385d01e7358..9418c464a16 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Infer_Patterns.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -30,6 +30,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -43,7 +45,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -70,7 +72,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -81,6 +83,11 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type User implements Node @source(subgraph: "Reviews", name: "Author") @variable(subgraph: "Accounts", name: "User_id", select: "id") @@ -88,9 +95,9 @@ type User implements Node @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -105,6 +112,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql index 39efdcc9201..ea9de6c49b1 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products.graphql @@ -1,11 +1,11 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -37,6 +37,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -53,7 +55,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -74,7 +76,7 @@ type Product implements Node @resolver(subgraph: "Reviews", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -114,7 +116,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -126,6 +128,8 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @@ -144,13 +148,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -165,6 +169,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql index 7f3716ef14d..835462a9839 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_AutoCompose_With_Node.graphql @@ -1,11 +1,11 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -38,6 +38,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -54,7 +56,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -71,7 +73,7 @@ type Author implements Node @variable(subgraph: "Reviews", name: "Author_id", select: "id") @resolver(subgraph: "Reviews", select: "{ authorById(id: $Author_id) }", arguments: [ { name: "Author_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Author_id) { ... on Author { ... Author } } }", arguments: [ { name: "Author_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Author_id) { ... on Author { ... Author } } }", arguments: [ { name: "Author_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Author_id) { ... on Author { ... Author } } }", arguments: [ { name: "Author_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Reviews") name: String! @@ -86,7 +88,7 @@ type Product implements Node @resolver(subgraph: "Reviews", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -126,7 +128,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: Author! @source(subgraph: "Reviews") body: String! @@ -138,6 +140,8 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @@ -155,7 +159,7 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -166,6 +170,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql index fb3e34023cc..7b5e68f83f6 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/DemoIntegrationTests.Accounts_And_Reviews_Products_With_Nodes.graphql @@ -1,11 +1,11 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Reviews", types: [ "User", "Review" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -56,6 +56,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -72,7 +74,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -93,7 +95,7 @@ type Product implements Node @resolver(subgraph: "Reviews", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -133,7 +135,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -145,6 +147,8 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @@ -163,13 +167,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -185,6 +189,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql index 97e35f88fab..20d4d0e8cfb 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/RequireTests.Require_Scalar_Arguments_No_Overloads.graphql @@ -1,13 +1,13 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Shipping", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -42,6 +42,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -58,7 +60,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -75,7 +77,7 @@ type Author implements Node @variable(subgraph: "Reviews", name: "Author_id", select: "id") @resolver(subgraph: "Reviews", select: "{ authorById(id: $Author_id) }", arguments: [ { name: "Author_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Author_id) { ... on Author { ... Author } } }", arguments: [ { name: "Author_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Author_id) { ... on Author { ... Author } } }", arguments: [ { name: "Author_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Author_id) { ... on Author { ... Author } } }", arguments: [ { name: "Author_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Reviews") name: String! @@ -101,7 +103,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -148,7 +150,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: Author! @source(subgraph: "Reviews") body: String! @@ -160,6 +162,8 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @@ -177,7 +181,7 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -188,6 +192,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/ResolverTests.Variables_Are_Computed_Even_Without_Resolver.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/ResolverTests.Variables_Are_Computed_Even_Without_Resolver.graphql index 2a66a6c9239..5f577702f49 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/ResolverTests.Variables_Are_Computed_Even_Without_Resolver.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/ResolverTests.Variables_Are_Computed_Even_Without_Resolver.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Appointment", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Appointment", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Patient1", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Patient1", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Appointment", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Appointment", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Patient1", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Patient1", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query } @@ -29,7 +29,7 @@ type Appointment implements Node @variable(subgraph: "Appointment", name: "Appointment_id", select: "id") @resolver(subgraph: "Appointment", select: "{ appointmentById(appointmentId: $Appointment_id) }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) @resolver(subgraph: "Appointment", select: "{ node(id: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Appointment") patient: IPatient! @@ -79,9 +79,9 @@ type Patient1 implements IPatient & Node @variable(subgraph: "Appointment", name: "Patient1_id", select: "id") @variable(subgraph: "Patient1", name: "Patient1_id", select: "id") @resolver(subgraph: "Appointment", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Patient1", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Patient1", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Patient1", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") { appointments("Returns the elements in the list that come after the specified cursor." after: String "Returns the elements in the list that come before the specified cursor." before: String "Returns the first _n_ elements from the list." first: Int "Returns the last _n_ elements from the list." last: Int): AppointmentsConnection @source(subgraph: "Appointment") @variable(subgraph: "Appointment", name: "after", argument: "after") diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql index 6876546c897..af94c6ce9b8 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Do_Not_Expose_Tags_On_Public_Schema.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -33,6 +33,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -46,7 +48,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -73,7 +75,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -84,6 +86,11 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type SomeType @variable(subgraph: "Accounts", name: "SomeType_id", select: "id") @resolver(subgraph: "Accounts", select: "{ someTypeById(id: $SomeType_id) }", arguments: [ { name: "SomeType_id", type: "ID!" } ]) @@ -97,13 +104,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -118,6 +125,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql index 2fd5c312ef9..88d4464b293 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Subgraphs_With_Review_Tag.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation } @@ -20,6 +20,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -33,6 +35,11 @@ type AddUserPayload { @source(subgraph: "Accounts") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type SomeType @variable(subgraph: "Accounts", name: "SomeType_id", select: "id") @resolver(subgraph: "Accounts", select: "{ someTypeById(id: $SomeType_id) }", arguments: [ { name: "SomeType_id", type: "ID!" } ]) @@ -45,10 +52,10 @@ type SomeType type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") @tag(name: "internal") @@ -60,6 +67,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql index c1228490052..dd128c2ebb3 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Exclude_Type_System_Members_With_Internal_Tag.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @tag(name: "review") { query: Query mutation: Mutation @@ -31,6 +31,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -44,7 +46,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -71,7 +73,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -82,18 +84,23 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type User implements Node @source(subgraph: "Reviews", name: "Author") @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Accounts") @source(subgraph: "Reviews") @@ -106,6 +113,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql index 5060f007d7c..ac93f377652 100644 --- a/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql +++ b/src/HotChocolate/Fusion/test/Composition.Tests/__snapshots__/TagTests.Expose_Tags_On_Public_Schema.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -33,6 +33,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -46,7 +48,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -73,7 +75,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -84,6 +86,11 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type SomeType @variable(subgraph: "Accounts", name: "SomeType_id", select: "id") @resolver(subgraph: "Accounts", select: "{ someTypeById(id: $SomeType_id) }", arguments: [ { name: "SomeType_id", type: "ID!" } ]) @@ -98,13 +105,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @variable(subgraph: "Reviews", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") @tag(name: "internal") @@ -120,6 +127,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/DataTests.cs b/src/HotChocolate/Fusion/test/Core.Tests/DataTests.cs new file mode 100644 index 00000000000..ffa256af637 --- /dev/null +++ b/src/HotChocolate/Fusion/test/Core.Tests/DataTests.cs @@ -0,0 +1,67 @@ +using CookieCrumble; +using HotChocolate.Execution; +using HotChocolate.Fusion.Composition; +using HotChocolate.Fusion.Composition.Features; +using HotChocolate.Fusion.Shared; +using HotChocolate.Skimmed.Serialization; +using HotChocolate.Types.Relay; +using Microsoft.Extensions.DependencyInjection; +using Xunit.Abstractions; +using static HotChocolate.Fusion.Shared.DemoProjectSchemaExtensions; +using static HotChocolate.Language.Utf8GraphQLParser; +using static HotChocolate.Fusion.TestHelper; + +namespace HotChocolate.Fusion; + +public class DataTests(ITestOutputHelper output) +{ + private readonly Func _logFactory = () => new TestCompositionLog(output); + + [Fact] + public async Task Fetch_Data_Across_Subgraphs() + { + // arrange + using var demoProject = await DemoProject.CreateAsync(); + + // act + var fusionGraph = await new FusionGraphComposer(logFactory: _logFactory).ComposeAsync( + new[] + { + demoProject.Reviews2.ToConfiguration(Reviews2ExtensionSdl), + demoProject.Accounts.ToConfiguration(AccountsExtensionSdl) + }); + + var executor = await new ServiceCollection() + .AddSingleton(demoProject.HttpClientFactory) + .AddSingleton(demoProject.WebSocketConnectionFactory) + .AddFusionGatewayServer() + .ConfigureFromDocument(SchemaFormatter.FormatAsDocument(fusionGraph)) + .BuildRequestExecutorAsync(); + + var request = Parse( + """ + query GetUser { + viewer { + data { + accountValue + reviewsValue + } + } + } + """); + + // act + await using var result = await executor.ExecuteAsync( + QueryRequestBuilder + .New() + .SetQuery(request) + .Create()); + + // assert + var snapshot = new Snapshot(); + CollectSnapshotData(snapshot, request, result, fusionGraph); + await snapshot.MatchAsync(); + + Assert.Null(result.ExpectQueryResult().Errors); + } +} \ No newline at end of file diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.snap index cc63296a821..2c502879458 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ConfigurationRewriterTests.Rewrite_HttpClient_Configuration.snap @@ -1,6 +1,6 @@ Original: --------------- -schema @fusion(version: 1) @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { +schema @fusion(version: 1) @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -14,6 +14,7 @@ type Query { userById(id: ID!): User @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! @resolver(subgraph: "Reviews2", select: "{ viewer }") @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -22,7 +23,7 @@ type Mutation { } type Subscription { - onNewReview: Review! @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + onNewReview: Review! @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -38,14 +39,19 @@ type Product @variable(subgraph: "Reviews2", name: "Product_id", select: "id") @ reviews: [Review!]! @source(subgraph: "Reviews2") } -type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { +type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @source(subgraph: "Reviews2") id: ID! @source(subgraph: "Reviews2") product: Product! @source(subgraph: "Reviews2") } -type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { +type SomeData { + accountValue: String! @source(subgraph: "Accounts") + reviewsValue: String! @source(subgraph: "Reviews2") +} + +type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @source(subgraph: "Reviews2") @source(subgraph: "Accounts") name: String! @source(subgraph: "Reviews2") @source(subgraph: "Accounts") @@ -53,6 +59,12 @@ type User implements Node @variable(subgraph: "Reviews2", name: "User_id", selec username: String! @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! @source(subgraph: "Reviews2") @source(subgraph: "Accounts") + latestReview: Review @source(subgraph: "Reviews2") + user: User @source(subgraph: "Accounts") +} + interface Node { id: ID! } @@ -80,7 +92,7 @@ scalar DateTime Rewritten: --------------- -schema @fusion(version: 1) @httpClient(clientName: "Reviews2", subgraph: "Reviews2", baseAddress: "http:\/\/client\/") @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") @httpClient(clientName: "Accounts", subgraph: "Accounts", baseAddress: "http:\/\/client\/") @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { +schema @fusion(version: 1) @transport(group: "Reviews2", subgraph: "Reviews2", location: "http:\/\/client\/") @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @transport(group: "Accounts", subgraph: "Accounts", location: "http:\/\/client\/") @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -94,6 +106,7 @@ type Query { userById(id: ID!): User @variable(subgraph: "Reviews2", name: "id", argument: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }") usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! @resolver(subgraph: "Reviews2", select: "{ viewer }") @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -102,7 +115,7 @@ type Mutation { } type Subscription { - onNewReview: Review! @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + onNewReview: Review! @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -118,14 +131,19 @@ type Product @variable(subgraph: "Reviews2", name: "Product_id", select: "id") @ reviews: [Review!]! @source(subgraph: "Reviews2") } -type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { +type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @source(subgraph: "Reviews2") id: ID! @source(subgraph: "Reviews2") product: Product! @source(subgraph: "Reviews2") } -type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { +type SomeData { + accountValue: String! @source(subgraph: "Accounts") + reviewsValue: String! @source(subgraph: "Reviews2") +} + +type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @source(subgraph: "Reviews2") @source(subgraph: "Accounts") name: String! @source(subgraph: "Reviews2") @source(subgraph: "Accounts") @@ -133,6 +151,12 @@ type User implements Node @variable(subgraph: "Reviews2", name: "User_id", selec username: String! @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! @source(subgraph: "Reviews2") @source(subgraph: "Accounts") + latestReview: Review @source(subgraph: "Reviews2") + user: User @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DataTests.Fetch_Data_Across_Subgraphs.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DataTests.Fetch_Data_Across_Subgraphs.snap new file mode 100644 index 00000000000..2191073c030 --- /dev/null +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DataTests.Fetch_Data_Across_Subgraphs.snap @@ -0,0 +1,222 @@ +User Request +--------------- +query GetUser { + viewer { + data { + accountValue + reviewsValue + } + } +} +--------------- + +QueryPlan +--------------- +{ + "document": "query GetUser { viewer { data { accountValue reviewsValue } } }", + "operation": "GetUser", + "rootNode": { + "type": "Sequence", + "nodes": [ + { + "type": "Parallel", + "nodes": [ + { + "type": "Resolve", + "subgraph": "Accounts", + "document": "query GetUser_1 { viewer { data { accountValue } } }", + "selectionSetId": 0 + }, + { + "type": "Resolve", + "subgraph": "Reviews2", + "document": "query GetUser_2 { reviewsValue }", + "selectionSetId": 2 + } + ] + }, + { + "type": "Compose", + "selectionSetIds": [ + 0, + 2 + ] + } + ] + } +} +--------------- + +QueryPlan Hash +--------------- +4870A9047BB973D0DE07AFF7E991C9397E87F8EF +--------------- + +Result +--------------- +{ + "data": { + "viewer": { + "data": { + "accountValue": "Account" + } + } + } +} +--------------- + +Fusion Graph +--------------- +schema + @fusion(version: 1) + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { + query: Query + mutation: Mutation + subscription: Subscription +} + +type Query { + productById(id: ID!): Product + @variable(subgraph: "Reviews2", name: "id", argument: "id") + @resolver(subgraph: "Reviews2", select: "{ productById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) + reviewById(id: ID!): Review + @variable(subgraph: "Reviews2", name: "id", argument: "id") + @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) + reviewOrAuthor: ReviewOrAuthor! + @resolver(subgraph: "Reviews2", select: "{ reviewOrAuthor }") + reviews: [Review!]! + @resolver(subgraph: "Reviews2", select: "{ reviews }") + userById(id: ID!): User + @variable(subgraph: "Reviews2", name: "id", argument: "id") + @resolver(subgraph: "Reviews2", select: "{ authorById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) + @variable(subgraph: "Accounts", name: "id", argument: "id") + @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ]) + users: [User!]! + @resolver(subgraph: "Accounts", select: "{ users }") + usersById(ids: [ID!]!): [User!]! + @variable(subgraph: "Accounts", name: "ids", argument: "ids") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") +} + +type Mutation { + addReview(input: AddReviewInput!): AddReviewPayload! + @variable(subgraph: "Reviews2", name: "input", argument: "input") + @resolver(subgraph: "Reviews2", select: "{ addReview(input: $input) }", arguments: [ { name: "input", type: "AddReviewInput!" } ]) + addUser(input: AddUserInput!): AddUserPayload! + @variable(subgraph: "Accounts", name: "input", argument: "input") + @resolver(subgraph: "Accounts", select: "{ addUser(input: $input) }", arguments: [ { name: "input", type: "AddUserInput!" } ]) +} + +type Subscription { + onNewReview: Review! + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") +} + +type AddReviewPayload { + review: Review + @source(subgraph: "Reviews2") +} + +type AddUserPayload { + user: User + @source(subgraph: "Accounts") +} + +type Product + @variable(subgraph: "Reviews2", name: "Product_id", select: "id") + @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) + @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) { + id: ID! + @source(subgraph: "Reviews2") + reviews: [Review!]! + @source(subgraph: "Reviews2") +} + +type Review implements Node + @variable(subgraph: "Reviews2", name: "Review_id", select: "id") + @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) + @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { + author: User! + @source(subgraph: "Reviews2") + body: String! + @source(subgraph: "Reviews2") + id: ID! + @source(subgraph: "Reviews2") + product: Product! + @source(subgraph: "Reviews2") +} + +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + +type User implements Node + @variable(subgraph: "Reviews2", name: "User_id", select: "id") + @variable(subgraph: "Accounts", name: "User_id", select: "id") + @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) + @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") + @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) + @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) + @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") + @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { + birthdate: Date! + @source(subgraph: "Accounts") + id: ID! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + name: String! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + reviews: [Review!]! + @source(subgraph: "Reviews2") + username: String! + @source(subgraph: "Accounts") +} + +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + +interface Node { + id: ID! +} + +union ReviewOrAuthor = User | Review + +input AddReviewInput { + authorId: Int! + body: String! + upc: Int! +} + +input AddUserInput { + birthdate: DateTime! + name: String! + username: String! +} + +"The `Date` scalar represents an ISO-8601 compliant date type." +scalar Date + +"The `DateTime` scalar represents an ISO-8601 compliant date time type." +scalar DateTime +--------------- diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql index 4f560323565..9cf4cb0d2ff 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_AutoCompose.graphql @@ -1,11 +1,11 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -37,6 +37,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -53,7 +56,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -74,7 +77,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -114,7 +117,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -126,10 +129,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -144,13 +151,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -165,6 +172,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.snap index 53b39ad0378..7006d6983f4 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Introspection.snap @@ -420,6 +420,13 @@ Result "name": null, "kind": "NON_NULL" } + }, + { + "name": "viewer", + "type": { + "name": null, + "kind": "NON_NULL" + } } ] }, @@ -629,6 +636,13 @@ Result "name": "SomeData", "kind": "OBJECT", "fields": [ + { + "name": "accountValue", + "type": { + "name": null, + "kind": "NON_NULL" + } + }, { "name": "data", "type": { @@ -642,6 +656,13 @@ Result "name": "Int", "kind": "SCALAR" } + }, + { + "name": "reviewsValue", + "type": { + "name": null, + "kind": "NON_NULL" + } } ] }, @@ -706,6 +727,33 @@ Result } ] }, + { + "name": "Viewer", + "kind": "OBJECT", + "fields": [ + { + "name": "data", + "type": { + "name": null, + "kind": "NON_NULL" + } + }, + { + "name": "latestReview", + "type": { + "name": "Review", + "kind": "OBJECT" + } + }, + { + "name": "user", + "type": { + "name": "User", + "kind": "OBJECT" + } + } + ] + }, { "name": "Error", "kind": "INTERFACE", @@ -802,12 +850,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -839,6 +887,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -855,7 +906,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -876,7 +927,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -916,7 +967,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -928,10 +979,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -946,13 +1001,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -967,6 +1022,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TopProducts.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TopProducts.snap index 33953848fb4..2d6bf319b78 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TopProducts.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TopProducts.snap @@ -113,12 +113,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -150,6 +150,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -166,7 +169,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -187,7 +190,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -227,7 +230,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -239,10 +242,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -257,13 +264,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -278,6 +285,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TypeName.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TypeName.snap index 758e23164f0..cb9ebaf62d0 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TypeName.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_Query_TypeName.snap @@ -124,12 +124,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -161,6 +161,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -177,7 +180,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -198,7 +201,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -238,7 +241,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -250,10 +253,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -268,13 +275,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -289,6 +296,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_With_Variables.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_With_Variables.snap index d394515cdf5..f22321898b5 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_With_Variables.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_And_Products_With_Variables.snap @@ -62,12 +62,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -99,6 +99,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -115,7 +118,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -136,7 +139,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -176,7 +179,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -188,10 +191,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -206,13 +213,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -227,6 +234,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql index dbd8477f2bf..9c7cc338699 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_AutoCompose.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -30,6 +30,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -43,7 +46,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -70,7 +73,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -81,18 +84,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -107,6 +117,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Batch_Requests.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Batch_Requests.snap index a1c922c7ee0..9cc77ebae77 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Batch_Requests.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Batch_Requests.snap @@ -106,10 +106,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) { query: Query @@ -150,6 +150,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -163,7 +166,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -190,7 +193,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -201,18 +204,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -227,6 +237,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById.snap index 9ae46132440..2100f65f59e 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById.snap @@ -52,10 +52,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -82,6 +82,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -95,7 +98,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -122,7 +125,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -133,18 +136,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -159,6 +169,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById_With_Invalid_Id_Value.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById_With_Invalid_Id_Value.snap index d166360e2eb..bb9ba8389b6 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById_With_Invalid_Id_Value.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserById_With_Invalid_Id_Value.snap @@ -55,10 +55,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -85,6 +85,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -98,7 +101,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -125,7 +128,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -136,18 +139,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -162,6 +172,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserReviews.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserReviews.snap index ff946583200..b2a85db57f6 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserReviews.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_GetUserReviews.snap @@ -119,10 +119,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -149,6 +149,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -162,7 +165,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -189,7 +192,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -200,18 +203,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -226,6 +236,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_Reformat_AuthorIds.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_Reformat_AuthorIds.snap index ecdeed6ed73..54de0f39334 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_Reformat_AuthorIds.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_Reformat_AuthorIds.snap @@ -73,10 +73,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) { query: Query @@ -117,6 +117,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -130,7 +132,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -157,7 +159,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -168,18 +170,23 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type User implements Node @source(subgraph: "Reviews", name: "Author") @variable(subgraph: "Reviews", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -195,6 +202,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_ReviewsUser.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_ReviewsUser.snap index 5656a2cabf2..d0561b6bd86 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_ReviewsUser.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Authors_And_Reviews_Query_ReviewsUser.snap @@ -194,10 +194,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -224,6 +224,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -237,7 +240,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -264,7 +267,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -275,18 +278,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -301,6 +311,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field.snap index 8c4a281eaa0..ebb9099e080 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field.snap @@ -97,12 +97,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -153,6 +153,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -169,7 +172,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -190,7 +193,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -230,7 +233,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -242,10 +245,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -260,13 +267,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -281,6 +288,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_From_Two_Subgraphs.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_From_Two_Subgraphs.snap index c4e78058507..f93fa411b24 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_From_Two_Subgraphs.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_From_Two_Subgraphs.snap @@ -131,12 +131,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -187,6 +187,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -203,7 +206,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -224,7 +227,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -264,7 +267,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -276,10 +279,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -294,13 +301,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -315,6 +322,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Review_Id.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Review_Id.snap index da5df1dc427..f39349fb7b3 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Review_Id.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Review_Id.snap @@ -95,12 +95,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -151,6 +151,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -167,7 +170,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -188,7 +191,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -228,7 +231,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -240,10 +243,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -258,13 +265,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -279,6 +286,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Unknown_Id.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Unknown_Id.snap index 1ba74b128a7..1cfbaa8f7e1 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Unknown_Id.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Fetch_User_With_Node_Field_Pass_In_Unknown_Id.snap @@ -106,12 +106,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -162,6 +162,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -178,7 +181,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -199,7 +202,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -239,7 +242,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -251,10 +254,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -269,13 +276,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -290,6 +297,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Node_Variables.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Node_Variables.snap index c9ecc7f87bb..bff960a2319 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Node_Variables.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Node_Variables.snap @@ -102,12 +102,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -158,6 +158,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -174,7 +177,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -195,7 +198,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -235,7 +238,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -247,10 +250,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -265,13 +272,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -286,6 +293,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Object_Variables.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Object_Variables.snap index 56629de65b9..0d6cda52dbb 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Object_Variables.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Object_Variables.snap @@ -70,12 +70,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -126,6 +126,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -142,7 +145,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -163,7 +166,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -203,7 +206,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -215,10 +218,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -233,13 +240,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -254,6 +261,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables.snap index 8f61abdf365..bbec108a1c0 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables.snap @@ -62,12 +62,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -118,6 +118,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -134,7 +137,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -155,7 +158,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -195,7 +198,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -207,10 +210,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -225,13 +232,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -246,6 +253,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName.snap index 91993e6cbb5..18039fadfb3 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName.snap @@ -61,12 +61,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -117,6 +117,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -133,7 +136,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -154,7 +157,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -194,7 +197,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -206,10 +209,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -224,13 +231,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -245,6 +252,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName_Two_RootSelections.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName_Two_RootSelections.snap index bf40391194a..dca2332705d 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName_Two_RootSelections.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Forward_Nested_Variables_No_OpName_Two_RootSelections.snap @@ -69,12 +69,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -125,6 +125,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -141,7 +144,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -162,7 +165,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -202,7 +205,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -214,10 +217,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -232,13 +239,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -253,6 +260,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.GetFirstPage_With_After_Null.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.GetFirstPage_With_After_Null.snap index 779cff7b97d..cf5525f098a 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.GetFirstPage_With_After_Null.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.GetFirstPage_With_After_Null.snap @@ -66,8 +66,8 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Appointment", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Appointment", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Appointment", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Appointment", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Appointment", types: [ "Patient1", "Appointment" ]) { query: Query } @@ -99,7 +99,7 @@ type Appointment implements Node @variable(subgraph: "Appointment", name: "Appointment_id", select: "id") @resolver(subgraph: "Appointment", select: "{ appointmentById(appointmentId: $Appointment_id) }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) @resolver(subgraph: "Appointment", select: "{ node(id: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Appointment") patient: IPatient! @@ -148,7 +148,7 @@ type PageInfo { type Patient1 implements IPatient & Node @variable(subgraph: "Appointment", name: "Patient1_id", select: "id") @resolver(subgraph: "Appointment", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") { appointments("Returns the elements in the list that come after the specified cursor." after: String "Returns the elements in the list that come before the specified cursor." before: String "Returns the first _n_ elements from the list." first: Int "Returns the last _n_ elements from the list." last: Int): AppointmentsConnection @source(subgraph: "Appointment") @variable(subgraph: "Appointment", name: "after", argument: "after") diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.snap index ee1670e8633..7653c3dfcc2 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Hot_Reload.snap @@ -18,6 +18,9 @@ }, { "name": "usersById" + }, + { + "name": "viewer" } ] } @@ -60,6 +63,9 @@ }, { "name": "usersById" + }, + { + "name": "viewer" } ] } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.QueryType_Parallel_Multiple_SubGraphs_WithArguments.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.QueryType_Parallel_Multiple_SubGraphs_WithArguments.snap index 79fb0614788..73683f71c14 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.QueryType_Parallel_Multiple_SubGraphs_WithArguments.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.QueryType_Parallel_Multiple_SubGraphs_WithArguments.snap @@ -158,14 +158,14 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Shipping", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -218,6 +218,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -234,7 +237,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -265,7 +268,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -312,7 +315,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -324,10 +327,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -342,13 +349,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -363,6 +370,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context.snap index f35519e8032..e8a0f00dfdb 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context.snap @@ -205,14 +205,14 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Shipping", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -265,6 +265,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -281,7 +284,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -312,7 +315,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -359,7 +362,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -371,10 +374,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -389,13 +396,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -410,6 +417,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_2.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_2.snap index 7dbe60c37a5..6ceca3e16c1 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_2.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_2.snap @@ -200,14 +200,14 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Shipping", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -260,6 +260,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -276,7 +279,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -307,7 +310,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -354,7 +357,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -366,10 +369,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -384,13 +391,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -405,6 +412,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_3.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_3.snap index c7ed1b439e8..573abe253f8 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_3.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.Require_Data_In_Context_3.snap @@ -254,14 +254,14 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Shipping", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews2", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) @node(subgraph: "Products", types: [ "Product" ]) { @@ -314,6 +314,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -330,7 +333,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -361,7 +364,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -408,7 +411,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -420,10 +423,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -438,13 +445,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -459,6 +466,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.TypeName_Field_On_QueryRoot.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.TypeName_Field_On_QueryRoot.snap index ead9844708d..3221c74ba17 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.TypeName_Field_On_QueryRoot.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/DemoIntegrationTests.TypeName_Field_On_QueryRoot.snap @@ -46,12 +46,12 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Products", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -83,6 +83,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -99,7 +102,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -120,7 +123,7 @@ type Product implements Node @resolver(subgraph: "Reviews2", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { dimension: ProductDimension! @source(subgraph: "Products") id: ID! @@ -160,7 +163,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -172,10 +175,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -190,13 +197,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -211,6 +218,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_NonNull.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_NonNull.snap index 7bdf9a2b522..4ddf19c3a85 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_NonNull.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_NonNull.snap @@ -83,10 +83,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) { query: Query @@ -127,6 +127,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -140,7 +142,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -167,7 +169,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -178,18 +180,23 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type User implements Node @source(subgraph: "Reviews", name: "Author") @variable(subgraph: "Reviews", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -205,6 +212,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_Nullable.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_Nullable.snap index b6e117458a4..312b087da99 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_Nullable.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Author_Nullable.snap @@ -103,10 +103,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) { query: Query @@ -147,6 +147,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -160,7 +162,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -187,7 +189,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -198,18 +200,23 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type User implements Node @source(subgraph: "Reviews", name: "Author") @variable(subgraph: "Reviews", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -225,6 +232,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Reviews_ListElement_Nullable.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Reviews_ListElement_Nullable.snap index c7ee730bfc6..8f551f48bfd 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Reviews_ListElement_Nullable.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/ErrorTests.Accounts_Offline_Reviews_ListElement_Nullable.snap @@ -91,10 +91,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Reviews", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Reviews", types: [ "User", "Review" ]) @node(subgraph: "Accounts", types: [ "User" ]) { query: Query @@ -135,6 +135,8 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -148,7 +150,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -175,7 +177,7 @@ type Review implements Node @variable(subgraph: "Reviews", name: "Review_id", select: "id") @resolver(subgraph: "Reviews", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews") body: String! @@ -186,18 +188,23 @@ type Review implements Node @source(subgraph: "Reviews") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") +} + type User implements Node @source(subgraph: "Reviews", name: "Author") @variable(subgraph: "Reviews", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -213,6 +220,13 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Accounts") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/EventStreamTests.Authors_And_Reviews_Subscription_OnNewReview.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/EventStreamTests.Authors_And_Reviews_Subscription_OnNewReview.snap index e029bdde694..4e8d7c75593 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/EventStreamTests.Authors_And_Reviews_Subscription_OnNewReview.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/EventStreamTests.Authors_And_Reviews_Subscription_OnNewReview.snap @@ -102,8 +102,8 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -130,6 +130,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -143,7 +146,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -170,7 +173,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -181,18 +184,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -207,6 +217,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql index 80d67628997..5fe336c1a06 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.AutoCompose.graphql @@ -1,9 +1,9 @@ schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -37,6 +37,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -53,7 +56,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -84,7 +87,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -131,7 +134,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -143,10 +146,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -161,13 +168,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -182,6 +189,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile.snap index bd983d977c7..55a3b61c378 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile.snap @@ -57,10 +57,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -94,6 +94,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -110,7 +113,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -141,7 +144,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -188,7 +191,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -200,10 +203,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -218,13 +225,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -239,6 +246,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile_2.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile_2.snap index 9c5a511aa69..ed3547299a6 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile_2.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/FileUploadTests.UploadFile_2.snap @@ -57,10 +57,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -94,6 +94,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -110,7 +113,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -141,7 +144,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -188,7 +191,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -200,10 +203,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -218,13 +225,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -239,6 +246,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List.snap index f5ba63611a8..c83492d980a 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List.snap @@ -67,8 +67,8 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Appointment", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Appointment", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Appointment", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Appointment", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Appointment", types: [ "Patient1", "Appointment" ]) { query: Query } @@ -100,7 +100,7 @@ type Appointment implements Node @variable(subgraph: "Appointment", name: "Appointment_id", select: "id") @resolver(subgraph: "Appointment", select: "{ appointmentById(appointmentId: $Appointment_id) }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) @resolver(subgraph: "Appointment", select: "{ node(id: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Appointment") patient: IPatient! @@ -149,7 +149,7 @@ type PageInfo { type Patient1 implements IPatient & Node @variable(subgraph: "Appointment", name: "Patient1_id", select: "id") @resolver(subgraph: "Appointment", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") { appointments("Returns the elements in the list that come after the specified cursor." after: String "Returns the elements in the list that come before the specified cursor." before: String "Returns the first _n_ elements from the list." first: Int "Returns the last _n_ elements from the list." last: Int): AppointmentsConnection @source(subgraph: "Appointment") @variable(subgraph: "Appointment", name: "after", argument: "after") diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment.snap index 2b41d67b9dd..3361aee9336 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment.snap @@ -99,10 +99,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Appointment", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Appointment", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Patient1", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Patient1", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Appointment", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Appointment", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Patient1", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Patient1", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Appointment", types: [ "Patient1", "Appointment" ]) @node(subgraph: "Patient1", types: [ "Patient1" ]) { query: Query @@ -142,7 +142,7 @@ type Appointment implements Node @variable(subgraph: "Appointment", name: "Appointment_id", select: "id") @resolver(subgraph: "Appointment", select: "{ appointmentById(appointmentId: $Appointment_id) }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) @resolver(subgraph: "Appointment", select: "{ node(id: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Appointment") patient: IPatient! @@ -192,9 +192,9 @@ type Patient1 implements IPatient & Node @variable(subgraph: "Appointment", name: "Patient1_id", select: "id") @variable(subgraph: "Patient1", name: "Patient1_id", select: "id") @resolver(subgraph: "Appointment", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Patient1", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Patient1", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Patient1", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") { appointments("Returns the elements in the list that come after the specified cursor." after: String "Returns the elements in the list that come before the specified cursor." before: String "Returns the first _n_ elements from the list." first: Int "Returns the last _n_ elements from the list." last: Int): AppointmentsConnection @source(subgraph: "Appointment") @variable(subgraph: "Appointment", name: "after", argument: "after") diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment_Fetch.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment_Fetch.snap index 2b41d67b9dd..3361aee9336 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment_Fetch.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/InterfaceTests.Query_Interface_List_With_Fragment_Fetch.snap @@ -99,10 +99,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Appointment", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Appointment", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Patient1", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Patient1", baseAddress: "ws:\/\/localhost:5000\/graphql") + @transport(subgraph: "Appointment", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Appointment", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Patient1", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Patient1", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") @node(subgraph: "Appointment", types: [ "Patient1", "Appointment" ]) @node(subgraph: "Patient1", types: [ "Patient1" ]) { query: Query @@ -142,7 +142,7 @@ type Appointment implements Node @variable(subgraph: "Appointment", name: "Appointment_id", select: "id") @resolver(subgraph: "Appointment", select: "{ appointmentById(appointmentId: $Appointment_id) }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) @resolver(subgraph: "Appointment", select: "{ node(id: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Appointment_id) { ... on Appointment { ... Appointment } } }", arguments: [ { name: "Appointment_id", type: "[ID!]!" } ], kind: "BATCH") { id: ID! @source(subgraph: "Appointment") patient: IPatient! @@ -192,9 +192,9 @@ type Patient1 implements IPatient & Node @variable(subgraph: "Appointment", name: "Patient1_id", select: "id") @variable(subgraph: "Patient1", name: "Patient1_id", select: "id") @resolver(subgraph: "Appointment", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Appointment", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Patient1", select: "{ node(id: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "ID!" } ]) - @resolver(subgraph: "Patient1", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Patient1", select: "{ nodes(ids: $Patient1_id) { ... on Patient1 { ... Patient1 } } }", arguments: [ { name: "Patient1_id", type: "[ID!]!" } ], kind: "BATCH") { appointments("Returns the elements in the list that come after the specified cursor." after: String "Returns the elements in the list that come before the specified cursor." before: String "Returns the first _n_ elements from the list." first: Int "Returns the last _n_ elements from the list." last: Int): AppointmentsConnection @source(subgraph: "Appointment") @variable(subgraph: "Appointment", name: "after", argument: "after") diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/IntrospectionTests.ShortCircuit_RootTypeName_Requests.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/IntrospectionTests.ShortCircuit_RootTypeName_Requests.snap index 1022f008486..c7065ec306e 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/IntrospectionTests.ShortCircuit_RootTypeName_Requests.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/IntrospectionTests.ShortCircuit_RootTypeName_Requests.snap @@ -4140,10 +4140,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Reviews2", baseAddress: "ws:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @webSocketClient(subgraph: "Accounts", baseAddress: "ws:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Reviews2", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "ws:\/\/localhost:5000\/graphql", kind: "WebSocket") { query: Query mutation: Mutation subscription: Subscription @@ -4170,6 +4170,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -4183,7 +4186,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -4210,7 +4213,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -4221,18 +4224,25 @@ type Review implements Node @source(subgraph: "Reviews2") } +type SomeData { + accountValue: String! + @source(subgraph: "Accounts") + reviewsValue: String! + @source(subgraph: "Reviews2") +} + type User implements Node @variable(subgraph: "Reviews2", name: "User_id", select: "id") @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -4247,6 +4257,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Node { id: ID! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment.snap index fa0d5be400f..ac3b69db1ab 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment.snap @@ -64,10 +64,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -101,6 +101,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -117,7 +120,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -148,7 +151,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -195,7 +198,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -207,10 +210,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -225,13 +232,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -246,6 +253,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment_Errors_Not_Null.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment_Errors_Not_Null.snap index addb2834444..dc143b5a2b4 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment_Errors_Not_Null.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_Inline_Fragment_Errors_Not_Null.snap @@ -69,10 +69,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -106,6 +106,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -122,7 +125,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -153,7 +156,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -200,7 +203,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -212,10 +215,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -230,13 +237,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -251,6 +258,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName.snap index 67c31ca89dc..31f07456fbc 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName.snap @@ -61,10 +61,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -98,6 +98,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -114,7 +117,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -145,7 +148,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -192,7 +195,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -204,10 +207,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -222,13 +229,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -243,6 +250,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName_Errors_Not_Null.snap b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName_Errors_Not_Null.snap index d1cf288b84d..484bb5a9194 100644 --- a/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName_Errors_Not_Null.snap +++ b/src/HotChocolate/Fusion/test/Core.Tests/__snapshots__/UnionTests.Error_Union_With_TypeName_Errors_Not_Null.snap @@ -65,10 +65,10 @@ Fusion Graph --------------- schema @fusion(version: 1) - @httpClient(subgraph: "Reviews2", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Accounts", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Products", baseAddress: "http:\/\/localhost:5000\/graphql") - @httpClient(subgraph: "Shipping", baseAddress: "http:\/\/localhost:5000\/graphql") { + @transport(subgraph: "Reviews2", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Accounts", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Products", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") + @transport(subgraph: "Shipping", location: "http:\/\/localhost:5000\/graphql", kind: "HTTP") { query: Query mutation: Mutation subscription: Subscription @@ -102,6 +102,9 @@ type Query { usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ]) + viewer: Viewer! + @resolver(subgraph: "Reviews2", select: "{ viewer }") + @resolver(subgraph: "Accounts", select: "{ viewer }") } type Mutation { @@ -118,7 +121,7 @@ type Mutation { type Subscription { onNewReview: Review! - @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIPTION") + @resolver(subgraph: "Reviews2", select: "{ onNewReview }", kind: "SUBSCRIBE") } type AddReviewPayload { @@ -149,7 +152,7 @@ type Product implements Node @resolver(subgraph: "Products", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Shipping", select: "{ productById(id: $Product_id) }", arguments: [ { name: "Product_id", type: "ID!" } ]) @resolver(subgraph: "Products", select: "{ node(id: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "ID!" } ]) - @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Products", select: "{ nodes(ids: $Product_id) { ... on Product { ... Product } } }", arguments: [ { name: "Product_id", type: "[ID!]!" } ], kind: "BATCH") { deliveryEstimate(zip: String!): DeliveryEstimate! @source(subgraph: "Shipping") @variable(subgraph: "Shipping", name: "zip", argument: "zip") @@ -196,7 +199,7 @@ type Review implements Node @variable(subgraph: "Reviews2", name: "Review_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ reviewById(id: $Review_id) }", arguments: [ { name: "Review_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $Review_id) { ... on Review { ... Review } } }", arguments: [ { name: "Review_id", type: "[ID!]!" } ], kind: "BATCH") { author: User! @source(subgraph: "Reviews2") body: String! @@ -208,10 +211,14 @@ type Review implements Node } type SomeData { + accountValue: String! + @source(subgraph: "Accounts") data: SomeData @source(subgraph: "Products") num: Int @source(subgraph: "Products") + reviewsValue: String! + @source(subgraph: "Reviews2") } type UploadProductPicturePayload { @@ -226,13 +233,13 @@ type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Reviews2", select: "{ authorById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Reviews2", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") + @resolver(subgraph: "Reviews2", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) - @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") { + @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") { birthdate: Date! @source(subgraph: "Accounts") id: ID! @@ -247,6 +254,16 @@ type User implements Node @source(subgraph: "Accounts") } +type Viewer { + data: SomeData! + @source(subgraph: "Reviews2") + @source(subgraph: "Accounts") + latestReview: Review + @source(subgraph: "Reviews2") + user: User + @source(subgraph: "Accounts") +} + interface Error { message: String! } diff --git a/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs b/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs index 894e1969c45..1d1b4469103 100644 --- a/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs +++ b/src/HotChocolate/Fusion/test/Shared/Accounts/AccountQuery.cs @@ -5,6 +5,8 @@ namespace HotChocolate.Fusion.Shared.Accounts; [GraphQLName("Query")] public class AccountQuery { + public Viewer Viewer { get; } = new(); + public IEnumerable GetUsers([Service] UserRepository repository) => repository.GetUsers(); @@ -26,4 +28,4 @@ public IEnumerable GetUsersById( } } } -} +} \ No newline at end of file diff --git a/src/HotChocolate/Fusion/test/Shared/Accounts/SomeData.cs b/src/HotChocolate/Fusion/test/Shared/Accounts/SomeData.cs new file mode 100644 index 00000000000..f615c4493ae --- /dev/null +++ b/src/HotChocolate/Fusion/test/Shared/Accounts/SomeData.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.Shared.Accounts; + +public class SomeData +{ + public string AccountValue => "Account"; +} \ No newline at end of file diff --git a/src/HotChocolate/Fusion/test/Shared/Accounts/Viewer.cs b/src/HotChocolate/Fusion/test/Shared/Accounts/Viewer.cs new file mode 100644 index 00000000000..f039a342518 --- /dev/null +++ b/src/HotChocolate/Fusion/test/Shared/Accounts/Viewer.cs @@ -0,0 +1,9 @@ +namespace HotChocolate.Fusion.Shared.Accounts; + +public class Viewer +{ + public SomeData Data { get; } = new(); + + public User? User([Service] UserRepository repository) + => repository.GetUser(1); +} \ No newline at end of file diff --git a/src/HotChocolate/Fusion/test/Shared/Reviews2/ReviewsQuery.cs b/src/HotChocolate/Fusion/test/Shared/Reviews2/ReviewsQuery.cs index ac8c21a13a4..66cf0ebc167 100644 --- a/src/HotChocolate/Fusion/test/Shared/Reviews2/ReviewsQuery.cs +++ b/src/HotChocolate/Fusion/test/Shared/Reviews2/ReviewsQuery.cs @@ -5,6 +5,8 @@ namespace HotChocolate.Fusion.Shared.Reviews2; [GraphQLName("Query")] public sealed class ReviewsQuery { + public Viewer Viewer { get; } = new(); + public IEnumerable GetReviews( [Service] ReviewRepository repository) => repository.GetReviews(); diff --git a/src/HotChocolate/Fusion/test/Shared/Reviews2/SomeData.cs b/src/HotChocolate/Fusion/test/Shared/Reviews2/SomeData.cs new file mode 100644 index 00000000000..9cf80bcbbac --- /dev/null +++ b/src/HotChocolate/Fusion/test/Shared/Reviews2/SomeData.cs @@ -0,0 +1,6 @@ +namespace HotChocolate.Fusion.Shared.Reviews2; + +public class SomeData +{ + public string ReviewsValue => "Reviews2"; +} \ No newline at end of file diff --git a/src/HotChocolate/Fusion/test/Shared/Reviews2/Viewer.cs b/src/HotChocolate/Fusion/test/Shared/Reviews2/Viewer.cs new file mode 100644 index 00000000000..5d35e770dd2 --- /dev/null +++ b/src/HotChocolate/Fusion/test/Shared/Reviews2/Viewer.cs @@ -0,0 +1,9 @@ +namespace HotChocolate.Fusion.Shared.Reviews2; + +public class Viewer +{ + public SomeData Data { get; } = new(); + + public Review? LatestReview([Service] ReviewRepository repository) + => repository.GetReview(1); +} \ No newline at end of file