示例#1
0
        public async Task <IActionResult> Post([FromBody] GraphQLQuery query)
        {
            if (query == null)
            {
                throw new ArgumentNullException();
            }

            var inputs         = query.Variables?.ToInputs();
            var executeOptions = new ExecutionOptions()
            {
                Schema = _schema,
                Query  = query.Query,
                Inputs = inputs
            };

            var results = await _documentExecuter.ExecuteAsync(executeOptions);

            if (results.Errors?.Count() > 0)
            {
                return(BadRequest(results));
            }

            return(Ok(results));
        }
示例#2
0
            public async Task <GraphQLResponse <TResponse> > SendQueryAsync <TResponse>(GraphQLRequest request, CancellationToken cancellationToken = default)
            {
                var res = await executer
                          .ExecuteAsync(_ =>
                {
                    _.Schema = schema;
                    _.Query  = request.Query;
                    _.Root   = root;
                })
                          .ConfigureAwait(false);

                if (res.Errors is ExecutionErrors err && err.Any())
                {
                    throw new Exception();
                }

                var text = await writer
                           .WriteToStringAsync(res)
                           .ConfigureAwait(false);

                return(await new NewtonsoftJsonSerializer()
                       .DeserializeFromUtf8StreamAsync <TResponse>(new MemoryStream(Encoding.UTF8.GetBytes(text)), cancellationToken)
                       .ConfigureAwait(false));
            }
        public async Task <IActionResult> Post([FromBody] GraphQLQuery query)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            var inputs           = query.Variables.ToInputs();
            var executionOptions = new ExecutionOptions
            {
                Schema = schema,
                Query  = query.Query,
                Inputs = inputs
            };

            var result = await documentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false);

            if (result.Errors?.Count > 0)
            {
                return(BadRequest(result));
            }

            return(Ok(result));
        }
示例#4
0
    Task <ExecutionResult> Execute(string query,
                                   string?operationName,
                                   JObject?variables,
                                   CancellationToken cancellation)
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

        ExecutionOptions options = new()
        {
            Schema            = schema,
            Query             = query,
            OperationName     = operationName,
            Inputs            = variables?.ToInputs(),
            CancellationToken = cancellation,
#if (DEBUG)
            ThrowOnUnhandledException = true,
            EnableMetrics             = true,
#endif
        };

        options.UseFluentValidation(ValidatorCacheBuilder.InstanceDI);

        return(executer.ExecuteAsync(options));
    }
        private async Task ExecuteAsync(HttpContext context, ISchemaFactory schemaService)
        {
            var schema = await schemaService.GetSchema();

            AbpGraphQLRequest request = null;

            if (HttpMethods.IsPost(context.Request.Method))
            {
                var mediaType = new MediaType(context.Request.ContentType);

                try
                {
                    if (mediaType.IsSubsetOf(JsonMediaType))
                    {
                        using (var sr = new StreamReader(context.Request.Body))
                        {
                            using (var jsonTextReader = new JsonTextReader(sr))
                            {
                                request = Serializer.Deserialize <AbpGraphQLRequest>(jsonTextReader);
                            }
                        }
                    }
                    else if (mediaType.IsSubsetOf(GraphQLMediaType))
                    {
                        request = new AbpGraphQLRequest();

                        using (var sr = new StreamReader(context.Request.Body))
                        {
                            request.Query = await sr.ReadToEndAsync();
                        }
                    }
                    else if (context.Request.Query.ContainsKey("query"))
                    {
                        request = new AbpGraphQLRequest
                        {
                            Query = context.Request.Query["query"]
                        };


                        if (context.Request.Query.ContainsKey("variables"))
                        {
                            request.Variables = JObject.Parse(context.Request.Query["variables"]);
                        }

                        if (context.Request.Query.ContainsKey("operationName"))
                        {
                            request.OperationName = context.Request.Query["operationName"];
                        }
                    }
                }
                catch (Exception e)
                {
                    await WriteErrorAsync(context, "An error occured while processing the GraphQL query", e);

                    return;
                }
            }
            else if (HttpMethods.IsGet(context.Request.Method))
            {
                if (!context.Request.Query.ContainsKey("query"))
                {
                    await WriteErrorAsync(context, "The 'query' query string parameter is missing");

                    return;
                }

                request = new AbpGraphQLRequest
                {
                    Query = context.Request.Query["query"]
                };
            }

            var queryToExecute = request.Query;

            if (!string.IsNullOrEmpty(request.NamedQuery))
            {
                var namedQueries = context.RequestServices.GetServices <INamedQueryProvider>();

                var queries = namedQueries
                              .SelectMany(dict => dict.Resolve())
                              .ToDictionary(pair => pair.Key, pair => pair.Value);

                queryToExecute = queries[request.NamedQuery];
            }

            var result = await _executor.ExecuteAsync(_ =>
            {
                _.Schema        = schema;
                _.Query         = queryToExecute;
                _.OperationName = request.OperationName;
                _.Inputs        = request.Variables.ToInputs();
                _.UserContext   = _options.BuildUserContext?.Invoke(context);

#if DEBUG
                _.ExposeExceptions = true;
#endif
            });

            var httpResult = result.Errors?.Count > 0
                ? HttpStatusCode.BadRequest
                : HttpStatusCode.OK;

            context.Response.StatusCode  = (int)httpResult;
            context.Response.ContentType = "application/json";

            await _writer.WriteAsync(context.Response.Body, result);
        }
示例#6
0
 private Task <ExecutionResult> ExecuteAsync(ExecutionOptions options)
 {
     return(_documentExecuter.ExecuteAsync(options));
 }
示例#7
0
        public virtual Task <ExecutionResult> ExecuteAsync(string operationName, string query, Inputs variables, object context, CancellationToken cancellationToken = default(CancellationToken))
        {
            var options = GetOptions(operationName, query, variables, context, cancellationToken);

            return(_documentExecuter.ExecuteAsync(options));
        }
        private async Task ExecuteAsync(HttpContext context, ISchemaFactory schemaService)
        {
            var schema = await schemaService.GetSchemaAsync();

            GraphQLRequest request = null;

            // c.f. https://graphql.org/learn/serving-over-http/#post-request

            if (HttpMethods.IsPost(context.Request.Method))
            {
                var mediaType = new MediaType(context.Request.ContentType);

                try
                {
                    if (mediaType.IsSubsetOf(_jsonMediaType))
                    {
                        using (var sr = new StreamReader(context.Request.Body))
                        {
                            // Asynchronous read is mandatory.
                            var json = await sr.ReadToEndAsync();

                            request = JObject.Parse(json).ToObject <GraphQLRequest>();
                        }
                    }
                    else if (mediaType.IsSubsetOf(_graphQlMediaType))
                    {
                        request = new GraphQLRequest();

                        using (var sr = new StreamReader(context.Request.Body))
                        {
                            request.Query = await sr.ReadToEndAsync();
                        }
                    }
                    else if (context.Request.Query.ContainsKey("query"))
                    {
                        request = new GraphQLRequest
                        {
                            Query = context.Request.Query["query"]
                        };

                        if (context.Request.Query.ContainsKey("variables"))
                        {
                            request.Variables = JObject.Parse(context.Request.Query["variables"]);
                        }

                        if (context.Request.Query.ContainsKey("operationName"))
                        {
                            request.OperationName = context.Request.Query["operationName"];
                        }
                    }
                }
                catch (Exception e)
                {
                    await WriteErrorAsync(context, "An error occurred while processing the GraphQL query", e);

                    return;
                }
            }
            else if (HttpMethods.IsGet(context.Request.Method))
            {
                if (!context.Request.Query.ContainsKey("query"))
                {
                    await WriteErrorAsync(context, "The 'query' query string parameter is missing");

                    return;
                }

                request = new GraphQLRequest
                {
                    Query = context.Request.Query["query"]
                };
            }

            var queryToExecute = request.Query;

            if (!String.IsNullOrEmpty(request.NamedQuery))
            {
                var namedQueries = context.RequestServices.GetServices <INamedQueryProvider>();

                var queries = namedQueries
                              .SelectMany(dict => dict.Resolve())
                              .ToDictionary(pair => pair.Key, pair => pair.Value);

                queryToExecute = queries[request.NamedQuery];
            }

            var dataLoaderDocumentListener = context.RequestServices.GetRequiredService <IDocumentExecutionListener>();

            var result = await _executer.ExecuteAsync(_ =>
            {
                _.Schema           = schema;
                _.Query            = queryToExecute;
                _.OperationName    = request.OperationName;
                _.Inputs           = request.Variables.ToInputs();
                _.UserContext      = _settings.BuildUserContext?.Invoke(context);
                _.ExposeExceptions = _settings.ExposeExceptions;
                _.ValidationRules  = DocumentValidator.CoreRules()
                                     .Concat(context.RequestServices.GetServices <IValidationRule>());
                _.ComplexityConfiguration = new ComplexityConfiguration
                {
                    MaxDepth      = _settings.MaxDepth,
                    MaxComplexity = _settings.MaxComplexity,
                    FieldImpact   = _settings.FieldImpact
                };
                _.Listeners.Add(dataLoaderDocumentListener);
            });

            context.Response.StatusCode = (int)(result.Errors == null || result.Errors.Count == 0
                ? HttpStatusCode.OK
                : result.Errors.Any(x => x.Code == RequiresPermissionValidationRule.ErrorCode)
                    ? HttpStatusCode.Unauthorized
                    : HttpStatusCode.BadRequest);

            context.Response.ContentType = "application/json";

            // Asynchronous write to the response body is mandatory.
            var encodedBytes = _utf8Encoding.GetBytes(JObject.FromObject(result).ToString());
            await context.Response.Body.WriteAsync(encodedBytes, 0, encodedBytes.Length);
        }
        public async Task <IActionResult> Post([FromBody] GraphQLQuery query, [FromHeader] string authorization)
        {
            var id = 0;

            if (_enableAuth)
            {
                if (authorization == null)
                {
                    Response.StatusCode = 401;
                    Response.Headers["WWW-Authenticate"] = "Bearer";
                    return(new EmptyResult());
                }

                var match = _headerRegex.Match(authorization);
                if (!match.Success)
                {
                    Response.StatusCode = 401;
                    Response.Headers["WWW-Authenticate"] = "Bearer";
                    return(new EmptyResult());
                }

                var token = match.Groups[1].Value;
                var(success, userId) = _login.VerifyToken(token);
                id = userId;
                if (!success)
                {
                    Response.StatusCode = 403;
                    return(new EmptyResult());
                }
            }

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

            var inputs           = query.Variables.ToInputs();
            var executionOptions = new ExecutionOptions
            {
                Schema        = _schema,
                Query         = query.Query,
                OperationName = query.OperationName,
                UserContext   = new InfoScreenUserContext(id),
                Inputs        = inputs
            };

            var result = await _documentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false);

            if (result.Errors != null)
            {
                foreach (var error in result.Errors)
                {
                    Console.Error.Write(error);
                }
            }

            if (result.Errors?.Count > 0)
            {
                return(BadRequest(result));
            }

            return(Ok(result));
        }
示例#10
0
        public override object ResolveContents(
            Sitecore.Mvc.Presentation.Rendering rendering,
            IRenderingConfiguration renderingConfig)
        {
            RenderingItem renderingItem = rendering.RenderingItem;

            if (renderingItem == null)
            {
                return(addPlaceHolderPath(rendering, renderingConfig));
            }

            string str = renderingItem.InnerItem[Sitecore.JavaScriptServices.Core.FieldIDs.JsonRendering.GraphQLQuery];

            if (string.IsNullOrWhiteSpace(str))
            {
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            AppConfiguration appConfiguration = this._configurationResolver.ResolveForItem(Context.Item);

            if (appConfiguration == null)
            {
                this._log.Warn("[JSS] - Rendering " + renderingItem.InnerItem.Paths.FullPath + " defined a GraphQL query to resolve its data, but when rendered on item " + Context.Item.Paths.FullPath + " it was not within a known JSS app path. The GraphQL query will not be used.", (object)this);
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            if (string.IsNullOrWhiteSpace(appConfiguration.GraphQLEndpoint))
            {
                this._log.Error("[JSS] - The JSS app " + appConfiguration.Name + " did not have a graphQLEndpoint set, but rendering " + renderingItem.InnerItem.Paths.FullPath + " defined a GraphQL query to resolve its data. The GraphQL query will not be used until an endpoint is defined on the app config.", (object)this);
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            IGraphQLEndpoint graphQlEndpoint;

            if (!this._graphQLEndpoints.TryGetValue(appConfiguration.GraphQLEndpoint, out graphQlEndpoint))
            {
                this._log.Error("[JSS] - The JSS app " + appConfiguration.Name + " is set to use GraphQL endpoint " + appConfiguration.GraphQLEndpoint + ", but no GraphQL endpoint was registered with this URL. GraphQL resolution will not be used.", (object)this);
                return(addPlaceHolderPath(rendering, renderingConfig));
            }
            GraphQLAwareRenderingContentsResolver.LocalGraphQLRequest localGraphQlRequest1 = new GraphQLAwareRenderingContentsResolver.LocalGraphQLRequest();
            localGraphQlRequest1.Query = str;
            GraphQLAwareRenderingContentsResolver.LocalGraphQLRequest localGraphQlRequest2 = localGraphQlRequest1;
            localGraphQlRequest2.LocalVariables.Add("contextItem", (object)Context.Item.ID.Guid.ToString());
            localGraphQlRequest2.LocalVariables.Add("datasource", (object)rendering.DataSource);

            //TODO Replace with correct path - Example of getting rendering field items to get path of card ID's
            string getCardPath = rendering.Item.Fields["sample1"].ToString();

            try
            {
                string   cardIDList = HttpContext.Current.Request.QueryString["cardIDList"];
                string[] cardIDs    = cardIDList.Split(',');
                int      cardInt    = 1;
                foreach (var cardID in cardIDs)
                {
                    localGraphQlRequest2.LocalVariables.Add("cardID" + cardInt, getCardPath + cardID);
                    cardInt++;
                }
            }
            catch (Exception ex)
            {
                this._log.Error("[JSS] - Something went wrong parsing the comma delimited query string parameter for cardIDList - " + ex.Message.ToString(), (object)this);
            }

            IDocumentExecuter executor = graphQlEndpoint.CreateDocumentExecutor();
            ExecutionOptions  options  = graphQlEndpoint.CreateExecutionOptions((GraphQLRequest)localGraphQlRequest2, !HttpContext.Current.IsCustomErrorEnabled);

            if (options == null)
            {
                throw new ArgumentException("Endpoint returned null options.");
            }
            TransformationResult transformationResult = graphQlEndpoint.SchemaInfo.QueryTransformer.Transform((GraphQLRequest)localGraphQlRequest2);

            if (transformationResult.Errors != null)
            {
                return (object)new ExecutionResult()
                       {
                           Errors = transformationResult.Errors
                       }
            }
            ;
            options.Query    = transformationResult.Document.OriginalQuery;
            options.Document = transformationResult.Document;
            if (options.Document.Operations.Any <Operation>((Func <Operation, bool>)(op => (uint)op.OperationType > 0U)))
            {
                throw new InvalidOperationException("Cannot use mutations or subscriptions in a datasource query. Use queries only.");
            }
            using (QueryTracer queryTracer = graphQlEndpoint.Performance.TrackQuery((GraphQLRequest)localGraphQlRequest2, options))
            {
                ExecutionResult result = this._asyncHelpers.RunSyncWithThreadContext <ExecutionResult>((Func <Task <ExecutionResult> >)(() => executor.ExecuteAsync(options)));
                graphQlEndpoint.Performance.CollectMetrics(graphQlEndpoint.SchemaInfo.Schema, (IEnumerable <Operation>)options.Document.Operations, result);
                new QueryErrorLog((ILogger) new BaseLogAdapter(this._log)).RecordQueryErrors(result);
                queryTracer.Result = result;
                //return (object)this._documentWriter.ToJObject((object)result);
                var jsonResultToConvert = (object)this._documentWriter.ToJObject((object)result);
                var jsonResult          = (JObject)jsonResultToConvert;
                jsonResult[PlaceholderPathKey] = rendering.Placeholder;
                return(jsonResult);
            }
        }
示例#11
0
        public async Task <RestResult> ProcessRequest(string path, string method, RestRequest req)
        {
            DBUser user       = null;
            var    proxyToken = req.Headers.GetValues("proxyToken");

            if (proxyToken != null && proxyToken.Length > 0)
            {
                var token = proxyToken[0];
                if (TokenManager.CheckToken(token))
                {
                    var username = TokenManager.GetTokenUsername(token);
                    user = UserManager.GetUser(username);
                }
                else
                {
                    return(new RestResult(new ErrorObject {
                        ErrorCode = ErrorCodes.InvalidLoginInformation,
                        Message = "The specified token is either invalid or expired.",
                        ErrorField = "proxyToken"
                    }.ToGraphQLJsonError(), MimeTypeMap.JSON, HttpStatusCode.Forbidden));
                }
            }

            var context = new GContext {
                Path   = path,
                Method = method,
                User   = user,
            };

            var body    = JsonConvert.DeserializeObject <GraphQLBody>(req.BodyData);
            var execute = await executer.ExecuteAsync(_ => {
                _.Schema        = schema;
                _.Query         = body.query;
                _.Root          = null;
                _.Inputs        = body.VariableToInputs();
                _.UserContext   = context;
                _.OperationName = body.operationName;
            });

            var result = new Dictionary <string, object> {
                { "data", execute.Data }
            };

            var gqlErrors = execute.Errors;

            if (gqlErrors?.Count > 0)
            {
                var errors = new List <ErrorObjectQ>();
                foreach (var err in gqlErrors)
                {
                    if (err.GetBaseException().GetType() == typeof(ErrorObjectException))
                    {
                        var baseErr = (ErrorObjectException)err.GetBaseException();
                        errors.Add(baseErr.ToQ());
                    }
                    else
                    {
                        errors.Add(new ErrorObject {
                            ErrorCode  = ErrorCodes.GraphQLError,
                            Message    = err.Message,
                            Locations  = err.Locations,
                            ErrorField = "graphql",
                        }.ToQ());
                    }
                }
                result.Add("errors", errors);
            }

            return(new RestResult(result));
        }
示例#12
0
        public async Task <APIGatewayProxyResponse> RunAsync(APIGatewayProxyRequest request, ILambdaContext context)
        {
            var query = JsonSerializer.Deserialize <GraphqlQuery>(request.Body,
                                                                  new JsonSerializerOptions {
                PropertyNameCaseInsensitive = true
            }
                                                                  );

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

            try
            {
                var execOptions = new ExecutionOptions
                {
                    Schema        = _schema,
                    Query         = query.Query,
                    OperationName = query.OperationName
                };

                var config = new MapperConfiguration(cfg =>
                {
                    cfg.CreateMap <ExecutionResult, GraphResult>();
                    cfg.CreateMap <ExecutionResult, GraphResultError>();
                });

                var    mapper = new Mapper(config);
                string output;

                var result = await _executer.ExecuteAsync(execOptions).ConfigureAwait(false);

                var serializerOptions = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                };
                if (result.Errors?.Count > 0)
                {
                    output = JsonSerializer.Serialize(mapper.Map <GraphResultError>(result), serializerOptions);
                }
                else
                {
                    output = JsonSerializer.Serialize(mapper.Map <GraphResult>(result), serializerOptions);
                }

                context.Logger.Log("GraphQL execution result: " + output);
                return(new APIGatewayProxyResponse
                {
                    StatusCode = 200,
                    Body = output,
                    Headers = new Dictionary <string, string> {
                        { "Content-Type", "application/json" },
                        { "Access-Control-Allow-Origin", "*" },
                        { "Access-Control-Allow-Headers", "*" },
                        { "Access-Control-Allow-Method", "*" }
                    }
                });
            }

            catch (Exception ex)
            {
                context.Logger.Log("Document exexuter exception " + ex);
                return(new APIGatewayProxyResponse
                {
                    StatusCode = 500,
                    Headers = new Dictionary <string, string> {
                        { "Content-Type", "application/json" },
                        { "Access-Control-Allow-Origin", "*" },
                        { "Access-Control-Allow-Headers", "*" },
                        { "Access-Control-Allow-Method", "*" }
                    }
                });
            }
        }
示例#13
0
        private async Task ExecuteAsync(HttpContext context, ISchema schema)
        {
            var request = Deserialize <GraphQLRequest>(context.Request.Body);

            // The following is a work around due to the lack of a Root Query.
            // However, while an Operation Name shouldn't be required, it may be useful for performance optimization / solving the N+1 problem.
            // Instead of multiple queries to obtain data, a single query might be much faster than multiple queries.

            // A Root Query is the recommended approach.
            // https://graphql-dotnet.github.io/docs/getting-started/query-organization/

            /*
             *  The N + 1 problem occurs when an application gets data from the database, and then loops through the result of that data.
             *  That means we call to the database again and again and again. In total, the application will call the database once for
             *  every row returned by the first query (N) plus the original query ( + 1).
             *  https://www.brentozar.com/archive/2018/07/common-entity-framework-problems-n-1/
             *
             *  https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping
             */

            switch (request?.OperationName)
            {
            case "AuthorQuery":
                schema = new Schema {
                    Query = new AuthorQuery()
                };
                break;

            case "AuthorsQuery":
            default:
                schema = new Schema {
                    Query = new AuthorsQuery()
                };
                break;

            case "PublisherQuery":
                schema = new Schema {
                    Query = new PublisherQuery()
                };
                break;

            case "PublishersQuery":
                schema = new Schema {
                    Query = new PublishersQuery()
                };
                break;

            case "TitleQuery":
                schema = new Schema {
                    Query = new TitleQuery()
                };
                break;

            case "TitlesQuery":
                schema = new Schema {
                    Query = new TitlesQuery()
                };
                break;
            }

            var result = await _executer.ExecuteAsync(_ =>
            {
                _.Schema        = schema;
                _.Query         = request?.Query;
                _.OperationName = request?.OperationName;
                _.Inputs        = request?.Variables.ToInputs();
                _.UserContext   = _settings.BuildUserContext?.Invoke(context);
                //_.ValidationRules = DocumentValidator.CoreRules().Concat(new [] { new InputValidationRule() });
                _.EnableMetrics = _settings.EnableMetrics;
                if (_settings.EnableMetrics)
                {
                    _.FieldMiddleware.Use <InstrumentFieldsMiddleware>();
                }
            });

            await WriteResponseAsync(context, result);
        }
示例#14
0
        public async Task Invoke(HttpContext httpContext)
        {
            var logger = httpContext.RequestServices.GetService <ILogger <GraphQlMiddleware> >();

            HttpRequest  request  = httpContext.Request;
            HttpResponse response = httpContext.Response;

            // GraphQL HTTP only supports GET and POST methods.
            if (request.Method != "GET" && request.Method != "POST")
            {
                response.Headers.Add("Allow", "GET, POST");
                response.StatusCode = 405;

                return;
            }

            // Check authorization
            if (_options.AuthorizationPolicy != null)
            {
                var authorizationService = httpContext.RequestServices.GetRequiredService <IAuthorizationService>();
                var authzResult          =
                    await authorizationService.AuthorizeAsync(httpContext.User, _options.AuthorizationPolicy);

                if (!authzResult.Succeeded)
                {
                    await httpContext.ForbidAsync();

                    return;
                }
            }

            GraphQlParameters parameters = await GetParametersAsync(request);

            ISchema schema = _schemaProvider.Create(httpContext.RequestServices);

            var result = await _executer.ExecuteAsync(options =>
            {
                options.Schema                  = schema;
                options.Query                   = parameters.Query;
                options.OperationName           = parameters.OperationName;
                options.Inputs                  = parameters.Variables.ToInputs();
                options.CancellationToken       = httpContext.RequestAborted;
                options.ComplexityConfiguration = _options.ComplexityConfiguration;
                options.UserContext             = httpContext;
                options.ExposeExceptions        = _options.ExposeExceptions;
                ConfigureDocumentExecutionListeners(options, _executionListeners);
            });

            if (result.Errors?.Count > 0)
            {
                logger.LogError("GraphQL Result {Errors}", result.Errors);
            }

            var writer = new DocumentWriter(indent: _options.FormatOutput);
            var json   = writer.Write(result);

            response.StatusCode  = 200;
            response.ContentType = "application/json; charset=utf-8";

            await response.WriteAsync(json);
        }
        public virtual Task <ExecutionResult> ExecuteAsync(string operationName, string query, JObject variables)
        {
            var options = GetOptions(operationName, query, variables);

            return(_documentExecuter.ExecuteAsync(options));
        }
示例#16
0
        internal async Task <ExecutionResult> ExecuteAsync(
            object rootObject,
            string query,
            string operationName,
            Inputs inputs,
            IUserContext userContext,
            IDependencyInjector dependencyInjector,
            ComplexityConfiguration complexityConfiguration,
            bool enableValidation = true,
            bool enableProfiling  = false,
            IEnumerable <IValidationRule> rules = null,
            CancellationToken cancellationToken = default,
            IEnumerable <IDocumentExecutionListener> listeners = null)
        {
            if (!enableValidation)
            {
                rules = new[] { new NoopValidationRule() };
            }

            var validationRules = rules?.ToArray() ?? new IValidationRule[0];
            var configuration   = new ExecutionOptions
            {
                Schema        = _schema,
                Root          = rootObject,
                Query         = query,
                OperationName = operationName,
                Inputs        = inputs,
                UserContext   = new Dictionary <string, object>()
                {
                    { typeof(IUserContext).FullName ?? nameof(IUserContext), userContext },
                    { typeof(IDependencyInjector).FullName ?? nameof(IDependencyInjector), dependencyInjector ?? new WrappedDependencyInjector(_constructor.TypeResolutionDelegate) },
                },
                ValidationRules         = validationRules.Any() ? validationRules : null,
                ComplexityConfiguration = complexityConfiguration,
                CancellationToken       = cancellationToken,
            };

            if (listeners != null)
            {
                foreach (var listener in listeners)
                {
                    configuration.Listeners.Add(listener);
                }
            }

            if (userContext is IDataLoaderContextProvider)
            {
                configuration.Listeners.Add(new DataLoaderListener());
            }

            if (enableProfiling)
            {
                configuration.FieldMiddleware.Use <InstrumentFieldsMiddleware>();
            }

            foreach (var middleware in _middleware)
            {
                configuration.FieldMiddleware.Use(middleware);
            }

            var result = await _documentExecutor.ExecuteAsync(configuration).ConfigureAwait(false);

            if (result.Errors != null && _errorTransformation != null)
            {
                result.Errors = _errorTransformation.Transform(result.Errors);
            }

            return(result);
        }
示例#17
0
        private async Task ExecuteAsync(HttpContext context, ISchema schema)
        {
            // Handle requests as per recommendation at http://graphql.org/learn/serving-over-http/
            var httpRequest = context.Request;
            var gqlRequest  = new GraphQLRequest();

            if (HttpMethods.IsGet(httpRequest.Method) || (HttpMethods.IsPost(httpRequest.Method) && httpRequest.Query.ContainsKey(GraphQLRequest.QueryKey)))
            {
                ExtractGraphQLRequestFromQueryString(httpRequest.Query, gqlRequest);
            }
            else if (HttpMethods.IsPost(httpRequest.Method))
            {
                if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out MediaTypeHeaderValue mediaTypeHeader))
                {
                    await WriteResponseAsync(context, HttpStatusCode.BadRequest, $"Invalid 'Content-Type' header: value '{httpRequest.ContentType}' could not be parsed.");

                    return;
                }

                switch (mediaTypeHeader.MediaType)
                {
                case JsonContentType:
                    gqlRequest = Deserialize <GraphQLRequest>(httpRequest.Body);
                    break;

                case GraphQLContentType:
                    gqlRequest.Query = await ReadAsStringAsync(httpRequest.Body);

                    break;

                default:
                    await WriteResponseAsync(context, HttpStatusCode.BadRequest, $"Invalid 'Content-Type' header: non-supported media type. Must be of '{JsonContentType}' or '{GraphQLContentType}'. See: http://graphql.org/learn/serving-over-http/.");

                    return;
                }
            }

            object userContext        = null;
            var    userContextBuilder = context.RequestServices.GetService <IUserContextBuilder>();

            if (userContextBuilder != null)
            {
                userContext = await userContextBuilder.BuildUserContext(context);
            }
            else
            {
                userContext = _options.BuildUserContext?.Invoke(context);
            }

            var result = await _executer.ExecuteAsync(x =>
            {
                x.Schema             = schema;
                x.Query              = gqlRequest.Query;
                x.OperationName      = gqlRequest.OperationName;
                x.Inputs             = gqlRequest.Variables.ToInputs();
                x.UserContext        = userContext;
                x.EnableMetrics      = true;
                x.ExposeExceptions   = true;
                x.SetFieldMiddleware = true;
                x.ValidationRules    = _options.ValidationRules.Concat(DocumentValidator.CoreRules()).ToList();

                if (_executionListeners != null)
                {
                    foreach (var listener in _executionListeners)
                    {
                        x.Listeners.Add(listener);
                    }
                }
            });

            await WriteResponseAsync(context, result);
        }
示例#18
0
        public async Task InvokeAsync(HttpContext context, ISchema schema)
        {
            if (!context.Request.Path.StartsWithSegments(_settings.Path))
            {
                await _next(context);

                return;
            }

            // Handle requests as per recommendation at http://graphql.org/learn/serving-over-http/
            var httpRequest = context.Request;
            var request     = new Request();

            if (HttpMethods.IsGet(httpRequest.Method) || (HttpMethods.IsPost(httpRequest.Method) && httpRequest.Query.ContainsKey(Request.QueryKey)))
            {
                ExtractGraphQLRequestFromQueryString(httpRequest.Query, request);
            }
            else if (HttpMethods.IsPost(httpRequest.Method))
            {
                if (!MediaTypeHeaderValue.TryParse(httpRequest.ContentType, out var mediaTypeHeader))
                {
                    await WriteBadRequestResponseAsync(context, _writer, $"Invalid 'Content-Type' header: value '{httpRequest.ContentType}' could not be parsed.");

                    return;
                }

                switch (mediaTypeHeader.MediaType)
                {
                case "application/json":
                    request = Deserialize <Request>(httpRequest.Body);
                    break;

                case "application/graphql":
                    request.Query = await ReadAsStringAsync(httpRequest.Body);

                    break;

                case "application/x-www-form-urlencoded":
                    var formCollection = await httpRequest.ReadFormAsync();

                    ExtractGraphQLRequestFromPostBody(formCollection, request);
                    break;

                default:
                    await WriteBadRequestResponseAsync(context, _writer, "Invalid 'Content-Type' header: non-supported media type. See: http://graphql.org/learn/serving-over-http/.");

                    return;
                }
            }
            else
            {
                await WriteBadRequestResponseAsync(context, _writer, $"Invalid request method: value '{httpRequest.Method}' could not be handled. See: http://graphql.org/learn/serving-over-http/.");
            }

            var start  = DateTime.UtcNow;
            var result = await _executer.ExecuteAsync(_ =>
            {
                _.Schema        = schema;
                _.Query         = request?.Query;
                _.OperationName = request?.OperationName;
                _.Inputs        = request?.Variables.ToInputs();
                _.UserContext   = new UserContext
                {
                    User = context.User
                };
                _.FieldMiddleware.Use <InstrumentFieldsMiddleware>();
                _.ValidationRules  = DocumentValidator.CoreRules().Concat(_rules);
                _.EnableMetrics    = _settings.EnableMetrics;
                _.ExposeExceptions = _settings.ExposeExceptions;
            });

            if (_settings.EnableMetrics && result.Errors == null)
            {
                result.EnrichWithApolloTracing(start);
            }

            if (result.Errors != null)
            {
                _logger.LogError("GraphQL execution error(s): {Errors}", result.Errors);
            }

            await WriteResponseAsync(context, result);
        }
示例#19
0
 private async Task <ExecutionResult> SetParamsAndExecute(ExecutionOptions executionOptions)
 {
     executionOptions.Schema = _schema;
     return(await _documentExecuter.ExecuteAsync(executionOptions));
 }