Skip to content

Commit

Permalink
Adds pure resolver for stitching (#4702)
Browse files Browse the repository at this point in the history
  • Loading branch information
PascalSenn authored Jan 30, 2022
1 parent 5da845f commit 8121059
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ public void Clear()

public IObjectType ObjectType => _parentType;

public IFieldSelection Selection => _parentContext.Selection;
public IFieldSelection Selection => _selection;

public Path Path => _path;

public IVariableValueCollection Variables => _parentContext.Variables;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public interface IPureResolverContext : IHasContextData
/// </summary>
IObjectType ObjectType { get; }

/// <summary>
/// Gets the current execution path.
/// </summary>
Path Path { get; }

/// <summary>
/// Gets the field selection for which a field resolver is
/// being executed.
Expand Down
5 changes: 0 additions & 5 deletions src/HotChocolate/Core/src/Types/Resolvers/IResolverContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ public interface IResolverContext : IPureResolverContext
/// <value></value>
NameString ResponseName { get; }

/// <summary>
/// Gets the current execution path.
/// </summary>
Path Path { get; }

/// <summary>
/// Indicates that the context has errors. To report new errors use <see cref="ReportError(IError)"/>
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using HotChocolate.Resolvers;
using HotChocolate.Types;

namespace HotChocolate.Stitching.Delegation;

internal static class RemoteFieldHelper
{
public static object? RemoteFieldResolver(IPureResolverContext context)
{
if (!context.Selection.Field.Directives.Contains(DirectiveNames.Computed) &&
context.Parent<object>() is IReadOnlyDictionary<string, object> dict)
{
var responseName = context.Selection.SyntaxNode.Alias == null
? context.Selection.SyntaxNode.Name.Value
: context.Selection.SyntaxNode.Alias.Value;

dict.TryGetValue(responseName, out var obj);
return DictionaryDeserializer.DeserializeResult(
context.Selection.Type,
obj,
context.Service<InputParser>(),
context.Path);
}

return null;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,15 @@ public override void OnBeforeCompleteType(
{
IReadOnlyDictionary<NameString, ISet<NameString>> externalFieldLookup =
completionContext.GetExternalFieldLookup();
if (externalFieldLookup.TryGetValue(
objectType.Name,
out ISet<NameString>? external))
if (externalFieldLookup.TryGetValue(objectType.Name, out ISet<NameString>? external))
{
foreach (ObjectFieldDefinition objectField in objectTypeDef.Fields)
{
if (external.Contains(objectField.Name) &&
_handledExternalFields.Add((objectTypeDef.Name, objectField.Name)))
{
FieldMiddleware handleDictionary =
FieldClassMiddlewareFactory.Create<DictionaryResultMiddleware>();
objectField.MiddlewareDefinitions.Insert(0, new(handleDictionary));
objectField.Resolvers = new FieldResolverDelegates(
pureResolver: RemoteFieldHelper.RemoteFieldResolver);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
using HotChocolate.Types;
using Snapshooter.Xunit;
using Xunit;
using HotChocolate.Execution.Processing;
using HotChocolate.Language;
using HotChocolate.Utilities;
using System.Linq;

namespace HotChocolate.Stitching.Integration
{
Expand Down Expand Up @@ -126,6 +130,54 @@ public async Task AutoMerge_AddLocal_Field_Execute()
result.ToJson().MatchSnapshot();
}

[Fact]
public async Task AutoMerge_CompileOperation()
{
// arrange
IHttpClientFactory httpClientFactory = CreateDefaultRemoteSchemas();

IRequestExecutor executor =
await new ServiceCollection()
.AddSingleton(httpClientFactory)
.AddGraphQL()
.AddQueryType(d => d.Name("Query").Field("local").Resolve("I am local."))
.AddRemoteSchema(_accounts)
.AddRemoteSchema(_inventory)
.AddRemoteSchema(_products)
.AddRemoteSchema(_reviews)
.BuildRequestExecutorAsync();

DocumentNode document = Utf8GraphQLParser.Parse(@"{
me {
id
name
reviews {
body
product {
upc
}
}
}
local
}");

OperationDefinitionNode operationDefinition =
document.Definitions.OfType<OperationDefinitionNode>().Single();

// act
IPreparedOperation operation =
OperationCompiler.Compile(
"a",
document,
operationDefinition,
executor.Schema,
executor.Schema.QueryType,
new(new DefaultTypeConverter()));

// assert
operation.Print().MatchSnapshot();
}

[Fact]
public async Task Directive_Variables_Are_Correctly_Rewritten()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
... on Query {
me @__execute(id: 0, kind: DEFAULT, type: COMPOSITE) {
... on User {
id @__execute(id: 2, kind: PURE, type: LEAF)
name @__execute(id: 3, kind: PURE, type: LEAF)
reviews @__execute(id: 4, kind: DEFAULT, type: COMPOSITE_LIST) {
... on Review {
body @__execute(id: 5, kind: PURE, type: LEAF)
product @__execute(id: 6, kind: DEFAULT, type: COMPOSITE) {
... on Product {
upc @__execute(id: 7, kind: PURE, type: LEAF)
}
}
}
}
}
}
local @__execute(id: 1, kind: DEFAULT, type: LEAF)
}
}

0 comments on commit 8121059

Please sign in to comment.