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)); }
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)); }
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); }
private Task <ExecutionResult> ExecuteAsync(ExecutionOptions options) { return(_documentExecuter.ExecuteAsync(options)); }
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)); }
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); } }
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)); }
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", "*" } } }); } }
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); }
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)); }
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); }
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); }
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); }
private async Task <ExecutionResult> SetParamsAndExecute(ExecutionOptions executionOptions) { executionOptions.Schema = _schema; return(await _documentExecuter.ExecuteAsync(executionOptions)); }