Skip to content

Commit

Permalink
Fixed Stitching Issues (#2491)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib committed Oct 27, 2020
1 parent 8cfda38 commit ab0edc3
Show file tree
Hide file tree
Showing 16 changed files with 129 additions and 65 deletions.
2 changes: 1 addition & 1 deletion src/HotChocolate/Core/src/Types/Contracts/ISchema.cs
Expand Up @@ -139,7 +139,7 @@ bool TryGetType<T>(NameString typeName, [NotNullWhen(true)]out T type)
/// <summary>
/// Generates a schema document.
/// </summary>
DocumentNode ToDocument();
DocumentNode ToDocument(bool includeSpecScalars = false);

/// <summary>
/// Prints the schema SDL representation.
Expand Down
3 changes: 2 additions & 1 deletion src/HotChocolate/Core/src/Types/Schema.cs
Expand Up @@ -181,7 +181,8 @@ public DirectiveType GetDirectiveType(NameString directiveName)
/// <summary>
/// Generates a schema document.
/// </summary>
public DocumentNode ToDocument() => SchemaSerializer.SerializeSchema(this);
public DocumentNode ToDocument(bool includeSpecScalars = false) =>
SchemaSerializer.SerializeSchema(this, includeSpecScalars);

/// <summary>
/// Returns the schema SDL representation.
Expand Down
5 changes: 3 additions & 2 deletions src/HotChocolate/Core/src/Types/SchemaSerializer.cs
Expand Up @@ -46,7 +46,8 @@ public static void Serialize(ISchema schema, TextWriter textWriter)
}

public static DocumentNode SerializeSchema(
ISchema schema)
ISchema schema,
bool includeSpecScalars = false)
{
if (schema is null)
{
Expand Down Expand Up @@ -75,7 +76,7 @@ public static void Serialize(ISchema schema, TextWriter textWriter)
IEnumerable<ScalarTypeDefinitionNode> scalarTypeDefinitions =
schema.Types
.OfType<ScalarType>()
.Where(t => !BuiltInTypes.IsBuiltInType(t.Name))
.Where(t => includeSpecScalars || !BuiltInTypes.IsBuiltInType(t.Name))
.OrderBy(t => t.Name.ToString(), StringComparer.Ordinal)
.Select(SerializeScalarType);

Expand Down
Expand Up @@ -64,7 +64,7 @@ public async Task InvokeAsync(IMiddlewareContext context)
UpdateContextData(context, result, delegateDirective);

object? value = ExtractData(result.Data, reversePath, context.ResponseName);
context.Result = new SerializedData(value);
context.Result = value is null or NullValueNode ? null : new SerializedData(value);
if (result.Errors is not null)
{
ReportErrors(delegateDirective.Schema, context, result.Errors);
Expand Down
Expand Up @@ -3,7 +3,6 @@
using System.Collections.Immutable;
using System.Linq;
using HotChocolate.Language;
using HotChocolate.Types;
using HotChocolate.Utilities;

namespace HotChocolate.Stitching.Delegation
Expand Down Expand Up @@ -138,11 +137,9 @@ public RemoteQueryBuilder SetRequestField(FieldNode field)
}

FieldNode requestField = _requestField;
if (_additionalFields.Count != 0
&& requestField.SelectionSet != null)
if (_additionalFields.Count != 0 && requestField.SelectionSet is not null)
{
var selections = new List<ISelectionNode>(
requestField.SelectionSet.Selections);
var selections = new List<ISelectionNode>(requestField.SelectionSet.Selections);
selections.AddRange(_additionalFields);
requestField = requestField.WithSelectionSet(
requestField.SelectionSet.WithSelections(selections));
Expand Down Expand Up @@ -182,7 +179,7 @@ public RemoteQueryBuilder SetRequestField(FieldNode field)
.Where(t => usedVariables.Contains(t.Variable.Name.Value))
.ToList();

for (int i = 0; i < variables.Count; i++)
for (var i = 0; i < variables.Count; i++)
{
VariableDefinitionNode variable = variables[i];
NameString typeName = variable.Type.NamedType().Name.Value;
Expand All @@ -194,13 +191,12 @@ public RemoteQueryBuilder SetRequestField(FieldNode field)
}
}

var fields = new FieldNode[] { current };
FieldNode[] fields = { current };

OperationDefinitionNode operationDefinition =
CreateOperation(_operationName, operation, fields, variables);

var definitions = new List<IDefinitionNode>();
definitions.Add(operationDefinition);
var definitions = new List<IDefinitionNode> { operationDefinition };
definitions.AddRange(_fragments);

return new DocumentNode(null, definitions);
Expand Down
@@ -1,11 +1,12 @@
using System;
using System.Linq;
using HotChocolate.Execution;
using HotChocolate.Language;
using HotChocolate.Resolvers;
using HotChocolate.Stitching.Properties;
using HotChocolate.Types;
using HotChocolate.Utilities;
using static HotChocolate.Stitching.ThrowHelper;
using static HotChocolate.Stitching.Properties.StitchingResources;

namespace HotChocolate.Stitching.Delegation.ScopedVariables
{
Expand All @@ -16,36 +17,32 @@ internal class ArgumentScopedVariableResolver : IScopedVariableResolver
ScopedVariableNode variable,
IInputType targetType)
{
if (context == null)
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}

if (variable == null)
if (variable is null)
{
throw new ArgumentNullException(nameof(variable));
}

if (!ScopeNames.Arguments.Equals(variable.Scope.Value))
{
throw new ArgumentException(
StitchingResources.ArgumentScopedVariableResolver_CannotHandleVariable,
ArgumentScopedVariableResolver_CannotHandleVariable,
nameof(variable));
}

IInputField? argument = context.Field.Arguments.FirstOrDefault(
t => t.Name.Value.EqualsOrdinal(variable.Name.Value));

if (argument == null)
if (argument is null)
{
throw new QueryException(ErrorBuilder.New()
.SetMessage(
StitchingResources.ArgumentScopedVariableResolver_InvalidArgumentName,
variable.Name.Value)
.SetCode(ErrorCodes.Stitching.ArgumentNotDefined)
.SetPath(context.Path)
.AddLocation(context.FieldSelection)
.Build());
throw ArgumentScopedVariableResolver_InvalidArgumentName(
variable.Name.Value,
context.FieldSelection,
context.Path);
}

return new VariableValue
Expand Down
Expand Up @@ -3,6 +3,7 @@
using HotChocolate.Resolvers;
using HotChocolate.Stitching.Properties;
using HotChocolate.Types;
using static HotChocolate.Stitching.Properties.StitchingResources;

namespace HotChocolate.Stitching.Delegation.ScopedVariables
{
Expand Down Expand Up @@ -31,12 +32,12 @@ internal class ContextDataScopedVariableResolver

if (!ScopeNames.ContextData.Equals(variable.Scope.Value))
{
throw new ArgumentException(StitchingResources
.ContextDataScopedVariableResolver_CannotHandleVariable,
throw new ArgumentException(
ContextDataScopedVariableResolver_CannotHandleVariable,
nameof(variable));
}

context.ContextData.TryGetValue(variable.Name.Value, out object data);
context.ContextData.TryGetValue(variable.Name.Value, out object? data);

IValueNode literal = data switch
{
Expand Down
@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HotChocolate.Execution;
using HotChocolate.Language;
using HotChocolate.Resolvers;
using HotChocolate.Stitching.Properties;
using HotChocolate.Types;
using HotChocolate.Utilities;
using static HotChocolate.Stitching.Properties.StitchingResources;

namespace HotChocolate.Stitching.Delegation.ScopedVariables
{
Expand All @@ -31,8 +28,7 @@ internal class FieldScopedVariableResolver
if (!ScopeNames.Fields.Equals(variable.Scope.Value))
{
throw new ArgumentException(
StitchingResources
.FieldScopedVariableResolver_CannotHandleVariable,
FieldScopedVariableResolver_CannotHandleVariable,
nameof(variable));
}

Expand Down Expand Up @@ -64,14 +60,10 @@ internal class FieldScopedVariableResolver
);
}

throw new QueryException(ErrorBuilder.New()
.SetMessage(
StitchingResources.FieldScopedVariableResolver_InvalidFieldName,
variable.Name.Value)
.SetCode(ErrorCodes.Stitching.FieldNotDefined)
.SetPath(context.Path)
.AddLocation(context.FieldSelection)
.Build());
throw ThrowHelper.FieldScopedVariableResolver_InvalidFieldName(
variable.Name.Value,
context.FieldSelection,
context.Path);
}
}
}
Expand Up @@ -24,12 +24,12 @@ internal class RootScopedVariableResolver
ScopedVariableNode variable,
IInputType targetType)
{
if (context == null)
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}

if (variable == null)
if (variable is null)
{
throw new ArgumentNullException(nameof(variable));
}
Expand All @@ -39,14 +39,10 @@ internal class RootScopedVariableResolver
return resolver.Resolve(context, variable, targetType);
}

throw new QueryException(ErrorBuilder.New()
.SetMessage(
StitchingResources.RootScopedVariableResolver_ScopeNotSupported,
variable.Scope.Value)
.SetCode(ErrorCodes.Stitching.ScopeNotDefined)
.SetPath(context.Path)
.AddLocation(context.FieldSelection)
.Build());
throw ThrowHelper.RootScopedVariableResolver_ScopeNotSupported(
variable.Scope.Value,
context.FieldSelection,
context.Path);
}
}
}
Expand Up @@ -3,6 +3,7 @@
using HotChocolate.Resolvers;
using HotChocolate.Stitching.Properties;
using HotChocolate.Types;
using static HotChocolate.Stitching.Properties.StitchingResources;

namespace HotChocolate.Stitching.Delegation.ScopedVariables
{
Expand All @@ -14,25 +15,25 @@ internal class ScopedContextDataScopedVariableResolver
ScopedVariableNode variable,
IInputType targetType)
{
if (context == null)
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}

if (variable == null)
if (variable is null)
{
throw new ArgumentNullException(nameof(variable));
}

if (targetType == null)
if (targetType is null)
{
throw new ArgumentNullException(nameof(targetType));
}

if (!ScopeNames.ScopedContextData.Equals(variable.Scope.Value))
{
throw new ArgumentException(StitchingResources
.ScopedCtxDataScopedVariableResolver_CannotHandleVariable,
throw new ArgumentException(
ScopedCtxDataScopedVariableResolver_CannotHandleVariable,
nameof(variable));
}

Expand Down
41 changes: 41 additions & 0 deletions src/HotChocolate/Stitching/src/Stitching/ThrowHelper.cs
@@ -1,5 +1,7 @@
using System;
using HotChocolate.Execution.Processing;
using HotChocolate.Language;
using HotChocolate.Stitching.Properties;
using static HotChocolate.Stitching.Properties.StitchingResources;

namespace HotChocolate.Stitching
Expand All @@ -17,5 +19,44 @@ internal static class ThrowHelper
new InvalidOperationException(string.Format(
ThrowHelper_BufferedRequest_OperationNotFound,
document));

public static GraphQLException ArgumentScopedVariableResolver_InvalidArgumentName(
string variableName,
FieldNode fieldSelection,
Path path) =>
new GraphQLException(ErrorBuilder.New()
.SetMessage(
StitchingResources.ArgumentScopedVariableResolver_InvalidArgumentName,
variableName)
.SetCode(ErrorCodes.Stitching.ArgumentNotDefined)
.SetPath(path)
.AddLocation(fieldSelection)
.Build());

public static GraphQLException FieldScopedVariableResolver_InvalidFieldName(
string variableName,
FieldNode fieldSelection,
Path path) =>
new GraphQLException(ErrorBuilder.New()
.SetMessage(
StitchingResources.FieldScopedVariableResolver_InvalidFieldName,
variableName)
.SetCode(ErrorCodes.Stitching.FieldNotDefined)
.SetPath(path)
.AddLocation(fieldSelection)
.Build());

public static GraphQLException RootScopedVariableResolver_ScopeNotSupported(
string scopeName,
FieldNode fieldSelection,
Path path) =>
new GraphQLException(ErrorBuilder.New()
.SetMessage(
StitchingResources.RootScopedVariableResolver_ScopeNotSupported,
scopeName)
.SetCode(ErrorCodes.Stitching.ScopeNotDefined)
.SetPath(path)
.AddLocation(fieldSelection)
.Build());
}
}
Expand Up @@ -28,7 +28,7 @@ internal class StitchingSchemaInterceptor : SchemaInterceptor
foreach (KeyValuePair<NameString, IRequestExecutor> executor in
context.GetRemoteExecutors())
{
allSchemas.Add(executor.Key, executor.Value.Schema.ToDocument());
allSchemas.Add(executor.Key, executor.Value.Schema.ToDocument(true));
}

IReadOnlyList<DocumentNode> typeExtensions = context.GetTypeExtensions();
Expand Down
Expand Up @@ -89,7 +89,7 @@ public void ArgumentDoesNotExist()

// assert
Assert.Collection(
Assert.Throws<QueryException>(a).Errors,
Assert.Throws<GraphQLException>(a).Errors,
t => Assert.Equal(ErrorCodes.Stitching.ArgumentNotDefined, t.Code));
}

Expand Down
Expand Up @@ -94,7 +94,7 @@ public void FieldDoesNotExist()

// assert
Assert.Collection(
Assert.Throws<QueryException>(a).Errors,
Assert.Throws<GraphQLException>(a).Errors,
t => Assert.Equal(ErrorCodes.Stitching.FieldNotDefined, t.Code));
}

Expand Down

0 comments on commit ab0edc3

Please sign in to comment.