c# - graphql-dotnet 如何从代码中调用查询
问题描述
我目前正在尝试从代码中调用 graphql-query 上的一个字段,而不使用 http 层。在一个测试用例中,我在字段解析器中成功使用了这个片段。断点命中。
var newContext = new ResolveFieldContext(context);
var query = context.ParentType;
var ticketQueryField = query.GetField("getTickets");
await (Task) ticketQueryField.Resolver.Resolve(context);
所以我认为可以ResolveFieldContext
用我真正需要的字段/参数填充副本并这样称呼它。但它非常......ResolveFieldContext
手动填充非常复杂。所以也许有一种更简单的方法来创建上下文。像:
var newContext = new ResolveFieldContext("query test { getTickets(id: 1) { number, title } }");
那真的很棒,在我的真实场景中,我想通过生成的查询访问一个不仅仅是字段。
为什么我要这样使用 Graph?我们在 GraphQL-Types 中使用的 Batch-Loader 非常适合我们的需求。
解决方案
您可以直接使用 http 执行 GraphQL 查询,如果您想要特定格式的数据,请DocumentExecutor
提供您自己的查询。DocumentWriter
有一个返回 JSON 的扩展方法,但您可以编写自己的。
这是用于测试查询的示例测试基类: https ://github.com/graphql-dotnet/graphql-dotnet/blob/master/src/GraphQL.Tests/BasicQueryTestBase.cs
这是一个返回 JSON 的控制台示例,不使用 http。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using GraphQL;
using GraphQL.Authorization;
using GraphQL.SystemTextJson;
using GraphQL.Types;
using GraphQL.Validation;
using Microsoft.Extensions.DependencyInjection;
namespace BasicSample
{
internal class Program
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "main")]
private static async Task Main()
{
using var serviceProvider = new ServiceCollection()
.AddSingleton<IAuthorizationEvaluator, AuthorizationEvaluator>()
.AddTransient<IValidationRule, AuthorizationValidationRule>()
.AddTransient(s =>
{
var authSettings = new AuthorizationSettings();
authSettings.AddPolicy("AdminPolicy", p => p.RequireClaim("role", "Admin"));
return authSettings;
})
.BuildServiceProvider();
string definitions = @"
type User {
id: ID
name: String
}
type Query {
viewer: User
users: [User]
}
";
var schema = Schema.For(definitions, builder => builder.Types.Include<Query>());
// remove claims to see the failure
var authorizedUser = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("role", "Admin") }));
string json = await schema.ExecuteAsync(_ =>
{
_.Query = "{ viewer { id name } }";
_.ValidationRules = serviceProvider
.GetServices<IValidationRule>()
.Concat(DocumentValidator.CoreRules);
_.RequestServices = serviceProvider;
_.UserContext = new GraphQLUserContext { User = authorizedUser };
});
Console.WriteLine(json);
}
}
/// <summary>
/// Custom context class that implements <see cref="IProvideClaimsPrincipal"/>.
/// </summary>
public class GraphQLUserContext : Dictionary<string, object>, IProvideClaimsPrincipal
{
/// <inheritdoc />
public ClaimsPrincipal User { get; set; }
}
/// <summary>
/// CLR type to map to the 'Query' graph type.
/// </summary>
public class Query
{
/// <summary>
/// Resolver for 'Query.viewer' field.
/// </summary>
[GraphQLAuthorize("AdminPolicy")]
public User Viewer() => new User { Id = Guid.NewGuid().ToString(), Name = "Quinn" };
/// <summary>
/// Resolver for 'Query.users' field.
/// </summary>
public List<User> Users() => new List<User> { new User { Id = Guid.NewGuid().ToString(), Name = "Quinn" } };
}
/// <summary>
/// CLR type to map to the 'User' graph type.
/// </summary>
public class User
{
/// <summary>
/// Resolver for 'User.id' field. Just a simple property.
/// </summary>
public string Id { get; set; }
/// <summary>
/// Resolver for 'User.name' field. Just a simple property.
/// </summary>
public string Name { get; set; }
}
}
推荐阅读
- javascript - 一旦屏幕通过特定点或 jsx 标签,如何获取滚动事件?
- c++ - C ++如何生成-32到32或-64到64之间的随机数并且不包括零值?
- javascript - 图像在 jQuery 中没有按顺序褪色?
- javascript - 在 JavaScript 中验证表单
- scala - 如何在 Spark Dataframe 上有效地执行此列操作?
- javascript - Javascript:如何使多个 div 从左侧滑动
- docker - 为什么“无”图像出现在 Docker 中,我们如何避免它
- jquery - 不附加在网格的左上角
- python - Python:将脚本的工作目录更改为不同的目录以读取常量
- c# - GCP Kubernetes Engine 上的 SMTP 出站电子邮件 (GSUITE) 不适用于 .Net Web 应用程序