public async Task <IReadOnlyQueryResult> ReadAsync(
            CancellationToken cancellationToken)
        {
            try
            {
                IReadOnlyQueryRequest request = _batch[_index++];

                DocumentNode document = request.Query is QueryDocument d
                    ? d.Document
                    : Utf8GraphQLParser.Parse(request.Query.ToSpan());

                OperationDefinitionNode operation =
                    document.GetOperation(request.OperationName);

                if (document != _previous)
                {
                    _fragments = document.GetFragments();
                    _visitationMap.Initialize(_fragments);
                }

                operation.Accept(
                    _visitor,
                    _visitationMap,
                    n => VisitorAction.Continue);

                _previous = document;
                document  = RewriteDocument(operation);
                operation = (OperationDefinitionNode)document.Definitions[0];
                IReadOnlyDictionary <string, object> variableValues =
                    MergeVariables(request.VariableValues, operation);

                request = QueryRequestBuilder.From(request)
                          .SetQuery(document)
                          .SetVariableValues(variableValues)
                          .AddExportedVariables(_exportedVariables)
                          .SetQueryName(null) // TODO ... should we create a name here?
                          .SetQueryHash(null)
                          .Create();

                var result =
                    (IReadOnlyQueryResult)await _executor.ExecuteAsync(
                        request, cancellationToken)
                    .ConfigureAwait(false);

                IsCompleted = _index >= _batch.Count;
                return(result);
            }
            catch (QueryException ex)
            {
                IsCompleted = true;
                return(QueryResult.CreateError(ex.Errors));
            }
            catch (Exception ex)
            {
                IsCompleted = true;
                return(QueryResult.CreateError(
                           _errorHandler.Handle(
                               _errorHandler.CreateUnexpectedError(ex).Build())));
            }
        }
Ejemplo n.º 2
0
            private async Task <IQueryResult> ExecuteNextAsync(
                IReadOnlyQueryRequest request,
                CancellationToken cancellationToken)
            {
                try
                {
                    DocumentNode document = request.Query is QueryDocument d
                        ? d.Document
                        : Utf8GraphQLParser.Parse(request.Query !.AsSpan());

                    OperationDefinitionNode operation =
                        document.GetOperation(request.OperationName);

                    if (document != _previous)
                    {
                        _fragments = document.GetFragments();
                        _visitationMap.Initialize(_fragments);
                    }

                    operation.Accept(
                        _visitor,
                        _visitationMap,
                        n => VisitorAction.Continue);

                    _previous = document;
                    document  = RewriteDocument(operation);
                    operation = (OperationDefinitionNode)document.Definitions[0];
                    IReadOnlyDictionary <string, object?>?variableValues =
                        MergeVariables(request.VariableValues, operation);

                    request = QueryRequestBuilder.From(request)
                              .SetQuery(document)
                              .SetVariableValues(variableValues)
                              .AddExportedVariables(_exportedVariables)
                              .SetQueryId(null) // TODO ... should we create a name here?
                              .SetQueryHash(null)
                              .Create();

                    return((IReadOnlyQueryResult)await _requestExecutor.ExecuteAsync(
                               request, cancellationToken)
                           .ConfigureAwait(false));
                }
                catch (GraphQLException ex)
                {
                    return(QueryResultBuilder.CreateError(ex.Errors));
                }
                catch (Exception ex)
                {
                    return(QueryResultBuilder.CreateError(
                               _errorHandler.Handle(
                                   _errorHandler.CreateUnexpectedError(ex).Build())));
                }
            }
Ejemplo n.º 3
0
    public async ValueTask InvokeAsync(IRequestContext context)
    {
        if (!_settings.Enable || context.ContextData.ContainsKey(SkipComplexityAnalysis))
        {
            await _next(context).ConfigureAwait(false);
        }
        else
        {
            if (context.DocumentId is not null &&
                context.OperationId is not null &&
                context.Document is not null)
            {
                string                  cacheId             = context.CreateCacheId(context.OperationId);
                DocumentNode            document            = context.Document;
                OperationDefinitionNode operationDefinition =
                    context.Operation?.Definition ??
                    document.GetOperation(context.Request.OperationName);

                if (!_cache.TryGetOperation(cacheId, out ComplexityAnalyzerDelegate? analyzer))
                {
                    analyzer = CompileAnalyzer(context, document, operationDefinition);
                }

                CoerceVariables(
                    context,
                    _coercionHelper,
                    operationDefinition.VariableDefinitions);

                var complexity = analyzer(context.Services, context.Variables !);
                var maximumAllowedComplexity = GetMaximumAllowedComplexity(context);
                context.ContextData[_settings.ContextDataKey] = complexity;

                if (complexity <= maximumAllowedComplexity)
                {
                    await _next(context).ConfigureAwait(false);
                }
                else
                {
                    context.Result = MaxComplexityReached(complexity, _settings.MaximumAllowed);
                }
            }