private static IEnumerable <Delegation.VariableValue> ResolveUsedRequestVariables( ISchema schema, NameString schemaName, ExtractedField extractedField, IReadOnlyDictionary <string, IValueNode> requestVariables, ExtractFieldQuerySyntaxRewriter rewriter) { foreach (VariableDefinitionNode variable in extractedField.Variables) { string name = variable.Variable.Name.Value; INamedInputType namedType = schema.GetType <INamedInputType>( variable.Type.NamedType().Name.Value); if (!requestVariables.TryGetValue(name, out IValueNode value)) { value = NullValueNode.Default; } value = rewriter.RewriteValueNode( schemaName, (IInputType)variable.Type.ToType(namedType), value); yield return(new Delegation.VariableValue ( name, variable.Type, value, variable.DefaultValue )); } }
private static void ResolveScopedVariableArguments( IResolverContext context, NameString schemaName, SelectionPathComponent component, IOutputField field, ICollection <Delegation.VariableValue> variables, ExtractFieldQuerySyntaxRewriter rewriter) { foreach (ArgumentNode argument in component.Arguments) { if (!field.Arguments.TryGetField(argument.Name.Value, out IInputField arg)) { throw new QueryException( ErrorBuilder.New() .SetMessage( StitchingResources.DelegationMiddleware_ArgumentNotFound, argument.Name.Value) .SetExtension("argument", argument.Name.Value) .SetCode(ErrorCodes.ArgumentNotFound) .Build()); } if (argument.Value is ScopedVariableNode sv) { Delegation.VariableValue variable = _resolvers.Resolve(context, sv, arg.Type); IValueNode value = rewriter.RewriteValueNode( schemaName, arg.Type, variable.Value); variables.Add(variable.WithValue(value)); } } }
private static IReadOnlyCollection <Delegation.VariableValue> CreateVariableValues( IMiddlewareContext context, NameString schemaName, IEnumerable <Delegation.VariableValue> scopedVariables, ExtractedField extractedField, ExtractFieldQuerySyntaxRewriter rewriter) { var values = new Dictionary <string, Delegation.VariableValue>(); foreach (Delegation.VariableValue value in scopedVariables) { values[value.Name] = value; } IReadOnlyDictionary <string, IValueNode> requestVariables = context.GetVariables(); foreach (Delegation.VariableValue value in ResolveUsedRequestVariables( context.Schema, schemaName, extractedField, requestVariables, rewriter)) { values[value.Name] = value; } return(values.Values); }
private static IReadOnlyList <Delegation.VariableValue> ResolveScopedVariables( IResolverContext context, NameString schemaName, OperationType operationType, IEnumerable <SelectionPathComponent> components, ExtractFieldQuerySyntaxRewriter rewriter) { var variables = new List <Delegation.VariableValue>(); IStitchingContext stitchingContext = context.Service <IStitchingContext>(); ISchema remoteSchema = stitchingContext.GetRemoteSchema(schemaName); IComplexOutputType type = remoteSchema.GetOperationType(operationType); SelectionPathComponent[] comps = components.Reverse().ToArray(); for (int i = 0; i < comps.Length; i++) { SelectionPathComponent component = comps[i]; if (!type.Fields.TryGetField(component.Name.Value, out IOutputField field)) { throw new QueryException(new Error { Message = string.Format( CultureInfo.InvariantCulture, StitchingResources.DelegationMiddleware_PathElementInvalid, component.Name.Value, type.Name) }); } ResolveScopedVariableArguments( context, schemaName, component, field, variables, rewriter); if (i + 1 < comps.Length) { if (!field.Type.IsComplexType()) { throw new QueryException(new Error { Message = StitchingResources .DelegationMiddleware_PathElementTypeUnexpected }); } type = (IComplexOutputType)field.Type.NamedType(); } } return(variables); }
private static IReadOnlyQueryRequest CreateQuery( IMiddlewareContext context, NameString schemaName, IImmutableStack <SelectionPathComponent> path) { var fieldRewriter = new ExtractFieldQuerySyntaxRewriter( context.Schema, context.Service <IEnumerable <IQueryDelegationRewriter> >()); OperationType operationType = context.Schema.IsRootType(context.ObjectType) ? context.Operation.Operation : OperationType.Query; ExtractedField extractedField = fieldRewriter.ExtractField( schemaName, context.Document, context.Operation, context.FieldSelection, context.ObjectType); IEnumerable <VariableValue> scopedVariables = ResolveScopedVariables( context, schemaName, operationType, path); IReadOnlyCollection <VariableValue> variableValues = CreateVariableValues( context, scopedVariables, extractedField); DocumentNode query = RemoteQueryBuilder.New() .SetOperation(operationType) .SetSelectionPath(path) .SetRequestField(extractedField.Field) .AddVariables(CreateVariableDefs(variableValues)) .AddFragmentDefinitions(extractedField.Fragments) .Build(); var requestBuilder = QueryRequestBuilder.New(); AddVariables(context, schemaName, requestBuilder, query, variableValues); requestBuilder.SetQuery(query); requestBuilder.AddProperty( WellKnownProperties.IsAutoGenerated, true); return(requestBuilder.Create()); }
public void ExtractField_WithCustomRewriters() { // arrange ISchema schema = Schema.Create( FileResource.Open("Stitching.graphql"), c => { c.RegisterType <DateTimeType>(); c.RegisterDirective <DelegateDirectiveType>(); c.RegisterDirective <ComputedDirectiveType>(); c.Use(next => context => Task.CompletedTask); }); DocumentNode query = Utf8GraphQLParser.Parse( FileResource.Open("StitchingQuery.graphql")); OperationDefinitionNode operation = query.Definitions .OfType <OperationDefinitionNode>().Single(); FieldNode selection = operation .SelectionSet.Selections .OfType <FieldNode>().First(); var rewriters = new List <IQueryDelegationRewriter> { new DummyRewriter() }; // act var rewriter = new ExtractFieldQuerySyntaxRewriter( schema, rewriters); ExtractedField extractedField = rewriter.ExtractField( "customer", query, operation, selection, schema.GetType <ObjectType>("Query")); // assert DocumentNode document = RemoteQueryBuilder.New() .SetRequestField(extractedField.Field) .AddFragmentDefinitions(extractedField.Fragments) .AddVariables(extractedField.Variables) .Build(); QuerySyntaxSerializer.Serialize(document) .MatchSnapshot(); }
public void ExtractField(string schemaFile, string queryFile) { // arrange ISchema schema = Schema.Create( FileResource.Open(schemaFile), c => { c.RegisterType <DateTimeType>(); c.RegisterDirective <DelegateDirectiveType>(); c.RegisterDirective <ComputedDirectiveType>(); c.Use(next => context => Task.CompletedTask); }); DocumentNode query = Parser.Default.Parse( FileResource.Open(queryFile)); OperationDefinitionNode operation = query.Definitions .OfType <OperationDefinitionNode>().Single(); FieldNode selection = operation .SelectionSet.Selections .OfType <FieldNode>().First(); // act var rewriter = new ExtractFieldQuerySyntaxRewriter(schema, Array.Empty <IQueryDelegationRewriter>()); ExtractedField extractedField = rewriter.ExtractField( "customer", query, operation, selection, schema.GetType <ObjectType>("Query")); // assert DocumentNode document = RemoteQueryBuilder.New() .SetRequestField(extractedField.Field) .AddFragmentDefinitions(extractedField.Fragments) .AddVariables(extractedField.Variables) .Build(); QuerySyntaxSerializer.Serialize(document) .MatchSnapshot(new SnapshotNameExtension( schemaFile, queryFile)); }