1

我在我的 graphql 结果中得到了一些额外的信息。除了我得到的数据和最终错误

  • 文档
  • 手术
  • 性能
  • 扩展

所以结果变得相当庞大。我注意到的另一个想法是文档和智能感知器的初始加载需要很长时间才能加载。

知道如何摆脱这些额外的数据吗?

graphQL 查询的结果:

graphQL 查询的结果

GraphQL 控制器

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ElectronConnectQuery.GraphQL;
using GraphQL;
using GraphQL.DataLoader;
using GraphQL.NewtonsoftJson;
using GraphQL.Types;
using GraphQL.Validation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace ElectronConnectQuery.Controllers.v1
{
    [Route("[controller]")]
    public class GraphQLController : Controller
    {
        private readonly IDocumentExecuter _documentExecuter;
        private readonly ISchema _schema;
        private readonly DataLoaderDocumentListener _listener;
        private readonly ILogger<GraphQLController> _logger;

        public GraphQLController(ISchema schema, IDocumentExecuter documentExecuter, DataLoaderDocumentListener listener, ILogger<GraphQLController> logger)
        {
            _schema = schema;
            _documentExecuter = documentExecuter;
            _listener = listener;
            _logger = logger;
        }

        [HttpPost]
        public async Task<IActionResult> Post([FromBody] GraphQLQuery query, [FromServices] IEnumerable<IValidationRule> validationRules)
        {
            if (query == null) { throw new ArgumentNullException(nameof(query)); }
            _logger.LogDebug("GraphQL received query:{Query}", query.Query);
            var inputs = query.Variables.ToInputs();
            var executionOptions = new ExecutionOptions
            {
                Schema = _schema,
                Query = query.Query,
                Inputs = inputs,
                ValidationRules = validationRules,
                EnableMetrics = false
            };

#if (DEBUG)
            executionOptions.EnableMetrics = true;
#endif

            executionOptions.Listeners.Add(_listener);

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

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

            return Ok(result);
        }
    }
}
4

2 回答 2

0

相反,如果您自己编写结果,请使用IDocumentWriter,它将正确序列化结果。

/// <summary>
/// Serializes an object hierarchy to a stream. Typically this would be serializing an instance of the ExecutionResult class into a JSON stream.
/// </summary>
public interface IDocumentWriter
{
    /// <summary>
    /// Asynchronously serializes the specified object to the specified stream.
    /// </summary>
    Task WriteAsync<T>(Stream stream, T value, CancellationToken cancellationToken = default);
}

还有一种扩展方法可以序列化为string.

public static async Task<string> WriteToStringAsync<T>(this IDocumentWriter writer, T value)

这个例子展示了使用中间件与控制器,但想法是一样的。

https://github.com/graphql-dotnet/examples/blob/529b530d7a6aad878b2757d776282fdc1cdcb595/src/AspNetCoreCustom/Example/GraphQLMiddleware.cs#L75-L81

private async Task WriteResponseAsync(HttpContext context, ExecutionResult result)
{
    context.Response.ContentType = "application/json";
    context.Response.StatusCode = result.Errors?.Any() == true ? (int)HttpStatusCode.BadRequest : (int)HttpStatusCode.OK;

    await _writer.WriteAsync(context.Response.Body, result);
}

您将需要包括GraphQL.SystemTextJsonGraphQL.NewtonSoftJson选择您的IDocumentWriter.

https://www.nuget.org/packages/GraphQL.SystemTextJson https://www.nuget.org/packages/GraphQL.NewtonsoftJson

于 2020-10-15T18:47:33.470 回答
0

我对控制器所做的更改是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using ElectronConnectQuery.GraphQL;
using GraphQL;
using GraphQL.DataLoader;
using GraphQL.Instrumentation;
using GraphQL.NewtonsoftJson;
using GraphQL.Types;
using GraphQL.Validation;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace ElectronConnectQuery.Controllers.v1
{
    [Route("[controller]")]
    public class GraphQLController : Controller
    {
        private readonly IDocumentExecuter _documentExecuter;
        private readonly ISchema _schema;
        private readonly DataLoaderDocumentListener _listener;
        private readonly ILogger<GraphQLController> _logger;
        private readonly IDocumentWriter _writer;

        public GraphQLController(ISchema schema, IDocumentExecuter documentExecuter, DataLoaderDocumentListener listener, ILogger<GraphQLController> logger, IDocumentWriter writer)
        {
            _schema = schema;
            _documentExecuter = documentExecuter;
            _listener = listener;
            _logger = logger;
            _writer = writer;
        }

        [HttpPost]
        public async Task Post([FromBody] GraphQLQuery query, [FromServices] IEnumerable<IValidationRule> validationRules)
        {
            if (query == null) { throw new ArgumentNullException(nameof(query)); }
            _logger.LogDebug("GraphQL received query:{Query}", query.Query);
            var inputs = query.Variables.ToInputs();
            var executionOptions = new ExecutionOptions
            {
                Schema = _schema,
                Query = query.Query,
                Inputs = inputs,
                ValidationRules = validationRules,
                EnableMetrics = false,
            };

            executionOptions.Listeners.Add(_listener);

            var result = await _documentExecuter.ExecuteAsync(opts =>
            {   
                opts.Schema = _schema;
                opts.Query = query.Query;
                opts.Inputs = inputs;
                opts.ValidationRules = validationRules;
                opts.FieldMiddleware.Use<InstrumentFieldsMiddleware>();
                opts.EnableMetrics = true;
            }).ConfigureAwait(false);

            result.EnrichWithApolloTracing(DateTime.Now);

            await _writer.WriteAsync(Response.Body, result);
        }


        private async Task WriteResponseAsync(HttpResponse response, ExecutionResult result)
        {
            response.ContentType = "application/json";
            response.StatusCode = result.Errors?.Any() == true ? (int)HttpStatusCode.BadRequest : (int)HttpStatusCode.OK;
            await _writer.WriteAsync(response.Body, result);
        }
    }
}

Startup.csConfigureServices 我添加了以下几行

  // kestrel
            services.Configure<KestrelServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            // IIS
            services.Configure<IISServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

我也注册了 DocumentWriter

services.AddScoped<IDocumentWriter, GraphQL.NewtonsoftJson.DocumentWriter>();
于 2020-10-18T19:28:55.703 回答