如何解决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);
}
}
}
解决方法
如果您自己编写结果,请使用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)
此示例显示了使用中间件还是使用控制器,但是想法是相同的。
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.SystemTextJson
或GraphQL.NewtonSoftJson
来选择IDocumentWriter
的实现。
https://www.nuget.org/packages/GraphQL.SystemTextJson https://www.nuget.org/packages/GraphQL.NewtonsoftJson
,我对控制器所做的更改是:
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.cs 在 ConfigureServices 我添加了以下几行
// kestrel
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
// IIS
services.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
我还注册了DocumentWriter
services.AddScoped<IDocumentWriter,GraphQL.NewtonsoftJson.DocumentWriter>();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。