【问题标题】:graphql-dotnet how to call a query from codegraphql-dotnet 如何从代码中调用查询
【发布时间】:2021-07-31 03:56:04
【问题描述】:

我目前正在尝试从代码中调用 graphql-query 上的一个字段,而不使用 http 层。在一个测试用例中,我在字段解析器中成功使用了这个 sn-p。断点命中。

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

那真是太棒了,在我的真实场景中,我想通过生成的查询访问一个不仅仅是字段。

为什么我要这样使用图表?我们在 GraphQL-Types 中使用的 Batch-Loader 非常适合我们的需求。

【问题讨论】:

    标签: c# .net-core graphql-dotnet


    【解决方案1】:

    您可以通过直接使用DocumentExecutor 并提供您自己的DocumentWriter 来执行不带http 的GraphQL 查询,如果您想要特定格式的数据。有一个返回 JSON 的扩展方法,但你可以自己编写。

    https://github.com/graphql-dotnet/graphql-dotnet/blob/master/src/GraphQL.NewtonsoftJson/DocumentWriter.cs

    这是一个用于测试查询的示例测试基类: 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; }
        }
    }
    

    【讨论】:

    • 这非常完美!非常非常感谢你!当我使用 ExecutionResult 时,我还获得了可以在 UnionType 中使用的强类型对象。 10/10!
    猜你喜欢
    • 2020-04-18
    • 1970-01-01
    • 2019-07-18
    • 2020-12-25
    • 1970-01-01
    • 2018-02-18
    • 2022-11-24
    • 1970-01-01
    • 2021-06-24
    相关资源
    最近更新 更多