Пример #1
0
        public async Task <T> MutateAsync <T>(Expression <Func <TMutation, T> > selector, CancellationToken token = default)
        {
            Check.IsNotNull(selector, nameof(selector));

            var asyncBatch    = new AsyncBatch(true);
            var mutation      = mutationFactory(asyncBatch);
            var resultFactory = SchemaExpressionVisitor.VisitValueAccessors(mutation, selector).Compile();

            await asyncBatch.ExecuteAsync(token);

            return(resultFactory(mutation, null));
        }
Пример #2
0
        public async Task <OperationResult> ExecuteRequestAsync(
            string queryText,
            IDictionary <string, object> variableValues,
            string operationName    = null,
            CancellationToken token = default)
        {
            Check.IsNotNullOrWhiteSpace(queryText, nameof(queryText));

            var document = new Parser().Parse(new Lexer().Tokenize(queryText));

            var operations = document.Definitions
                             .OfType <OperationDefinition>();

            if (operationName != null)
            {
                operations = operations
                             .Where(x => x.Name == operationName);
            }

            var operationCount = operations
                                 .Take(2)
                                 .Count();

            if (operationCount == 0)
            {
                throw new InvalidOperationException("No operations defined");
            }
            else if (operationCount > 1)
            {
                throw new InvalidOperationException("Multiple operations defined");
            }

            var operation = operations
                            .First();

            var fragments = document.Definitions
                            .OfType <FragmentDefinition>()
                            .ToList();

            if (operation.OperationType != OperationType.Query && mutationFactory == null)
            {
                throw new InvalidOperationException("No mutation defined");
            }

            var asyncBatch = new AsyncBatch(operation.OperationType == OperationType.Query);
            var target     = operation.OperationType == OperationType.Query
                ? (GraphQLObject)queryFactory(asyncBatch)
                : mutationFactory(asyncBatch);

            var errors = new List <GraphQLError>();
            var variableDefinitions = (operation.VariableDefinitions ?? Enumerable.Empty <VariableDefinition>())
                                      .ToDictionary(x => x.Name, x => x);
            var variableTypes = (operation.VariableDefinitions ?? Enumerable.Empty <VariableDefinition>())
                                .ToDictionary(x => x.Name, x => x.Type);
            var variables = new VariableValues((operation.VariableDefinitions ?? Enumerable.Empty <VariableDefinition>())
                                               .ToDictionary(x => x.Name, x => variableValues.TryGetValue(x.Name, out var value) ? value : x.DefaultValue));
            var fields = await FieldCollector.CollectFields(variables, variableTypes, target, operation.SelectionSet, fragments, errors, logger, exceptionFilter, token);

            errors.AddRange(variables.UnusedVariables
                            .Select(x => new GraphQLError($"Variable '${x}' is not used. ", new[] { variableDefinitions[x].Location }))
                            .ToList()
                            );

            if (errors.Any())
            {
                return(new OperationResult(null, errors));
            }

            try
            {
                await asyncBatch.ExecuteAsync(token);
            }
            catch (GraphQLException ex)
            {
                return(new OperationResult(null, ex.Errors));
            }

            var result = Apply(null, fields, errors);

            return(new OperationResult(result, errors));
        }