• GraphQL:打造自己的Directive库


      GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

                                            ——出自 https://graphql.cn

      HotChocolate可以通过自定义Directive来对字段的值进行转换和处理,下在的例子就是给字符串给字符串类型的值转大写和替换。

    using HotChocolate;
    using HotChocolate.Data;
    using HotChocolate.Execution;
    using HotChocolate.Types;
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    
    namespace GraphQLBase003
    {
        class Program
        {
            static void Main(string[] args)
    {
                DirectiveDemo.Run();
            }
        }
      
        public class DirectiveDemo
        {
            public static void Run()
    {
                var schema = SchemaBuilder.New()
                    .AddProjections()
                    .AddQueryType<Query>()
                    .AddDirectiveType<UpperDirectiveType>()
                    .AddDirectiveType<ReplaceDirectiveType>()
                    .Create();
                var executor = schema.MakeExecutable();
                Console.WriteLine("原name=abcde ");
                Console.WriteLine("--------------转大写-------------------");
                Console.WriteLine(executor.Execute("{ student{id name @upper(name:\"this is test\")  age} }").ToJson());
                Console.WriteLine("--------------a替换成1 -------------------");
                Console.WriteLine(executor.Execute("{ student{id name @replace(old:\"a\",new:\"1\")  age} }").ToJson());
                Console.WriteLine("--------------然后全部转大写-.a替换成1 -------------------");
                Console.WriteLine(executor.Execute("{ student{id name @upper(name:\"this is test\") @replace(old:\"a\",new:\"1\")  age} }").ToJson());
                Console.WriteLine("--------------a替换成1.然后全部转大写-------------------");
                Console.WriteLine(executor.Execute("{ student{id name @replace(old:\"a\",new:\"1\")  @upper(name:\"this is test\") age} }").ToJson());
            }
            public class Query
            {
                [UseProjection]
                public Student GetStudent()
    {
                    return new Student
                    {
                        Id = 1,
                        Name = "abcde",
                        Age = 234
                    };
                }
                [UseProjection]
                public List<Student> GetStudents()
                {
                    return new List<Student>{
                        new Student
                        {
                            Id = 100,
                            Name = "aBcD",
                            Age=10
                        },
                        new Student
                        {
                            Id = 101,
                            Name = "EFGH",
                            Age=20
                        }
                    };
                }
            }
            public class Student
            {
                public int Id { get; set; }
                public string Name { get; set; }
                public int Age { get; set; }
            }
    
            public class UpperDirectiveType : DirectiveType<UpperDirective>
            {
                protected override void Configure(IDirectiveTypeDescriptor<UpperDirective> descriptor)
    {
                    descriptor.Name("upper");
                    descriptor.Location(DirectiveLocation.Field);
                    descriptor.Use(next => context =>
                    {
                        foreach (var directive in context.FieldSelection.Directives)
                        {
                            if (directive.Name.Value == "upper")
                            {
                                if (context.Field.Member.MemberType == System.Reflection.MemberTypes.Property)
                                {
                                    var pro = context.Field.Member as PropertyInfo;
                                    var obj = context.GetType().GetMethod("Parent").MakeGenericMethod(context.ObjectType.RuntimeType).Invoke(context, new object[0]);
                                    var value = pro.GetValue(obj);
                                    pro.SetValue(obj, value.ToString().ToUpper());                            
                                }
                            }
                        }
                        return next.Invoke(context);
                    });
                }
            }
    
            public class UpperDirective
            {
                public string Name
                {
                    get;
                    set;
                }
            }
    
            public class ReplaceDirectiveType : DirectiveType<ReplaceDirective>
            {
    
                protected override void Configure(IDirectiveTypeDescriptor<ReplaceDirective> descriptor)
    {
                    descriptor.Name("replace");
                    descriptor.Location(DirectiveLocation.Field);
                    descriptor.Use(next => context =>
                    {
                        foreach (var directive in context.FieldSelection.Directives)
                        {
                            if (directive.Name.Value == "replace")
                            {
                                var dir = new Dictionary<string, object>();
                                foreach (var item in directive.Arguments)
                                {
                                    dir.Add(item.Name.Value?.ToLower(), item.Value.Value);
                                }
                                if (context.Field.Member.MemberType == System.Reflection.MemberTypes.Property)
                                {                                
                                    var s = context.Parent<Student>();
                                    var pro = context.Field.Member as PropertyInfo;
                                    var obj = context.GetType().GetMethod("Parent").MakeGenericMethod(context.ObjectType.RuntimeType).Invoke(context, new object[0]);
                                    var value = pro.GetValue(obj);
                                    pro.SetValue(obj, value.ToString().Replace(dir["old"].ToString(), dir["new"].ToString()));                                
                                }
                            }
                        }
                        return next.Invoke(context);
                    });
    
    
                }
            }
    
            public class ReplaceDirective
            {
                public string Old
                {
                    get;
                    set;
                }
                public string New
                {
                    get;
                    set;
                }
            }
        }
    }

      upper和replace两个Directive处理的还比较粗糙,这里主要说明Directive的定义方式;在调用这些Directive时,按照前后顺序调用,多个Directive可以同时生效,和asp.net core的中间件原理相近,上例的后两个调用 name @upper @replace和name @replace @upper返回的结果是不一样的。

     
      想要更快更方便的了解相关知识,可以关注微信公众号 
     

     

  • 相关阅读:
    vijos1194 Domino
    vijos1603迷宫
    怎样实现App安装来源追踪
    怎样实现App安装来源追踪
    怎么在Chrome和Firefox浏览器中清除HSTS设置?
    怎么在Chrome和Firefox浏览器中清除HSTS设置?
    element UI排坑记(一):判断tabs组件是否切换
    ZooKeeper分布式锁的实现原理
    ZooKeeper分布式锁的实现原理
    TensorFlow框架 入门笔记
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/15859135.html
Copyright © 2020-2023  润新知