Example #1
0
        public async Task <ExecuteGQLQueryResults> ExecuteQuery(string queryTemplate, IDictionary <string, object> parameters)
        {
            var schema = await _schemaService.GetSchemaAsync();

            var gqlSettings    = _settingsAccessor.Value;
            var tokenizedQuery = await _liquidTemplateManager.RenderStringAsync(queryTemplate, NullEncoder.Default, parameters.Select(x => new KeyValuePair <string, FluidValue>(x.Key, FluidValue.Create(x.Value, _templateOptions))));

            var result = new ExecuteGQLQueryResults()
            {
                TokenizedQuery = tokenizedQuery
            };

            result.Result = await _executer.ExecuteAsync(_ =>
            {
                _.Schema           = schema;
                _.Query            = tokenizedQuery;
                _.UserContext      = gqlSettings.BuildUserContext?.Invoke(_httpContextAccessor.HttpContext);
                _.ExposeExceptions = gqlSettings.ExposeExceptions;
                _.ValidationRules  = DocumentValidator.CoreRules()
                                     .Concat(_validationRules);
                _.ComplexityConfiguration = new ComplexityConfiguration
                {
                    MaxDepth      = gqlSettings.MaxDepth,
                    MaxComplexity = gqlSettings.MaxComplexity,
                    FieldImpact   = gqlSettings.FieldImpact
                };
                _.Listeners.Add(_dataLoaderDocumentListener);
            });

            return(result);
        }
        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);
        }
Example #3
0
        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))
                        {
                            using (var jsonTextReader = new JsonTextReader(sr))
                            {
                                request = _serializer.Deserialize <GraphQLRequest>(jsonTextReader);
                            }
                        }
                    }
                    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();

                        request.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();

                request.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 _executer.ExecuteAsync(_ =>
            {
                _.Schema           = schema;
                _.Query            = queryToExecute;
                _.OperationName    = request.OperationName;
                _.Inputs           = request.Variables.ToInputs();
                _.UserContext      = _settings.BuildUserContext?.Invoke(context);
                _.ExposeExceptions = _settings.ExposeExceptions;
            });

            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);
        }