Exemplo n.º 1
0
        public async Task ExecuteAsync()
        {
            if (!ParseBuildRequest())
            {
                return;
            }
            AssignRequestOperation();
            if (_requestContext.Failed)
            {
                return;
            }

            // signal to prepare/deserialize variables; in http/web scenario, we cannot parse variables immediately -
            // we do not know variable types yet. Now that we have parsed and prepared query, we have var types;
            // we fire this event, parent GraphQLHttpServer will handle it and deserializer variables.
            _server.Events.OnRequestPrepared(_requestContext);
            BuildOperationVariables();
            if (_requestContext.Failed)
            {
                return;
            }

            BuildDirectiveContexts();

            var opMapping = _requestContext.Operation.OperationTypeDef.Mappings[0];
            var topScope  = new OutputObjectScope(new RequestPath(), null, opMapping);

            _requestContext.Response.Data = topScope;
            await ExecuteOperationAsync(_requestContext.Operation, topScope);
        }
Exemplo n.º 2
0
        private async Task ExecuteOperationAsync(GraphQLOperation op, OutputObjectScope topScope)
        {
            var mappedTopSubset = op.SelectionSubset.MappedSubSets[0];
            var topMappedItems  = mappedTopSubset.MappedItems;
            var parallel        = _parallelQueryEnabled && op.OperationType == OperationType.Query &&
                                  op.SelectionSubset.Items.Count > 1;

            var executers = new List <OperationFieldExecuter>();

            foreach (var mappedItem in topMappedItems)
            {
                switch (mappedItem)
                {
                case MappedFragmentSpread mfs:
                    _requestContext.AddInputError($"Top selection items may not be fragments", mfs.Spread);
                    return;

                case MappedSelectionField mappedField:
                    var opExecuter = new OperationFieldExecuter(_requestContext, mappedField, topScope);
                    executers.Add(opExecuter);
                    break;
                }
            }

            if (parallel)
            {
                await ExecuteAllParallel(executers);
            }
            else
            {
                await ExecuteAllNonParallel(executers);
            }

            // Save results from op fields into top scope; we do it here, after all threads finished, to avoid concurrency issues
            // and preserve output field order
            foreach (var ex in executers)
            {
                topScope.SetValue(ex.ResultKey, ex.Result);
            }
        }