看过基础篇的都知道,GraphQL创建Schema有两种方式,Schema First和Graph Type,前者使用GraphQL Schema Language类似于EF的DB First;后者和EF 的Code First相似。使用GraphQL请求流程大致如下图所示,今天我就用Graph Type通过控制台程序简单的介绍下大致使用过程:
1、安装GraphQL包
GraphQL包提供了GraphQL.Types命名空间,GraphQL的使用离不开GraphQL.Types。
2、自定义数据模型
1 /// <summary> 2 /// 自定义客户类 3 /// </summary> 4 [Table("t_customer")] 5 public partial class CustomerEntity 6 { 7 public CustomerEntity() 8 { 9 10 } 11 /// <summary> 12 /// 主键GuID 13 /// </summary> 14 public string Guid { get; set; } 15 /// <summary> 16 /// 中文性 17 /// </summary> 18 [Required, Column("code_cn", TypeName = Constants.NVarChar255)] 19 public string Code_CN { get; set; } 20 /// <summary> 21 /// 中文名 22 /// </summary> 23 [Required, Column("name_cn", TypeName = Constants.NVarChar255)] 24 public string Name_CN { get; set; } 25 /// <summary> 26 /// 英文性 27 /// </summary> 28 [Required, Column("code_en", TypeName = Constants.NVarChar255)] 29 public string Code_EN { get; set; } 30 /// <summary> 31 /// 英文名 32 /// </summary> 33 [Required, Column("name_en", TypeName = Constants.NVarChar255)] 34 public string Name_EN { get; set; } 35 //中文姓,中文名,英文姓,英文名,性别,生日,默认出票方式,国籍,电子邮箱,工作单位,备注 36 37 /// <summary> 38 /// 性别 39 /// </summary> 40 [Required, Column("sex", TypeName = Constants.NVarChar255)] 41 public string Sex { get; set; } 42 /// <summary> 43 /// 生日 44 /// </summary> 45 [Required, Column("birthday", TypeName = Constants.NVarChar255)] 46 public string BirthDay { get; set; } 47 /// <summary> 48 /// 出票方式 49 /// </summary> 50 [Required, Column("drawerway", TypeName = Constants.NVarChar255)] 51 public string DrawerWay { get; set; } 52 /// <summary> 53 /// 国籍 54 /// </summary> 55 [Required, Column("country", TypeName = Constants.NVarChar255)] 56 public string Country { get; set; } 57 /// <summary> 58 /// 电子邮箱 59 /// </summary> 60 [Required, Column("email", TypeName = Constants.NVarChar255)] 61 public string EMail { get; set; } 62 /// <summary> 63 /// 工作单位 64 /// </summary> 65 [Required, Column("workunit", TypeName = Constants.NVarChar255)] 66 public string WorkUnit { get; set; } 67 /// <summary> 68 /// 备注 69 /// </summary> 70 [Required, Column("remark", TypeName = Constants.Text)] 71 public string Remark { get; set; } 72 }
3、GraphQL的数据模型
定义GraphQL的数据模型该模型继承自ObjectGraphType,对自定义数据模型CustomerEntity的属性进行相应映射。
1 /// <summary> 2 /// GraphQL的数据模型:继承自ObjectGraphType,并传递范型CustomerEntity 3 /// </summary> 4 public class CustomerEntityType : ObjectGraphType<CustomerEntity> 5 { 6 //在构造函数中,对属性作影射 7 public CustomerEntityType() 8 { 9 Name = "customers"; 10 Field(x => x.Guid); 11 Field(x=>x.BirthDay); 12 Field(x => x.Code_CN); 13 Field(x => x.Code_EN); 14 Field(x => x.Country); 15 Field(x => x.DrawerWay); 16 Field(x => x.EMail); 17 Field(x => x.Name_CN); 18 Field(x => x.Name_EN); 19 Field(x => x.Remark); 20 Field(x => x.Sex); 21 Field(x => x.WorkUnit); 22 Field<ListGraphType<CustomerEntityType>>("Customers"); 23 } 24 25 }
4、定义操作模型
在这里我在啰嗦一遍GraphQL的操作包括 Query(Select), Mutation (Create,Update,Delete),Subscription (订阅),在这里我把所有请求查询的字段映射到了CustomerRepository的调用上。
1 public class CustomerRepository : ICustomerRepository 2 { 3 //public List<CustomerEntity> CustomersList { get; set; } 4 public IEnumerable<CustomerEntity> GetAll() 5 { 6 var jack = new CustomerEntity 7 { 8 Guid = Guid.NewGuid().ToString(), 9 Code_CN = "张", 10 Name_CN = "三", 11 Code_EN = "Jack", 12 Name_EN = "Jack-Jie", 13 Sex = "男" 14 }; 15 var lx = new CustomerEntity 16 { 17 Guid = Guid.NewGuid().ToString(), 18 Code_CN = "李", 19 Name_CN = "五", 20 Code_EN = "lx", 21 Name_EN = "lx-Jie", 22 Sex = "男" 23 }; 24 var wz = new CustomerEntity 25 { 26 Guid = Guid.NewGuid().ToString(), 27 Code_CN = "王", 28 Name_CN = "三", 29 Code_EN = "wz", 30 Name_EN = "Wz-Jie", 31 Sex = "女" 32 }; 33 34 var query = new List<CustomerEntity> { jack, lx, wz }; 35 return query; 36 } 37 public CustomerEntity GetByID(string guid) 38 { 39 return GetAll().FirstOrDefault(x=>x.Guid == guid); 40 } 41 }
查询操作:
1 /// <summary> 2 /// GraphQL查询 3 /// </summary> 4 public class QueryAction : ObjectGraphType 5 { 6 IEnumerable<CustomerEntity> customers = null; 7 ICustomerRepository repository = new CustomerRepository(); 8 9 public QueryAction() 10 { 11 Field<ListGraphType<CustomerEntityType>>(//在构造函数中定义查询操作 12 name: "customers", //注意这个名字,后边查询的时候需要对应 13 arguments: new QueryArguments //定义查询参数 14 { 15 new QueryArgument<StringGraphType> 16 { 17 Name = "Guid", 18 Description = "The Guid for the CustomerEntity" 19 }, 20 new QueryArgument<StringGraphType> 21 { 22 Name = "BirthDay", 23 Description = "The BirthDay for the CustomerEntity" 24 }, 25 new QueryArgument<StringGraphType> 26 { 27 Name = "Code_CN", 28 Description = "The Code_CN for the CustomerEntity" 29 }, 30 new QueryArgument<StringGraphType> 31 { 32 Name = "Code_EN", 33 Description = "The Code_EN for CustomerEntity" 34 }, 35 new QueryArgument<StringGraphType> 36 { 37 Name = "Country", 38 Description = "The Country for CustomerEntity" 39 }, 40 new QueryArgument<StringGraphType> 41 { 42 Name = "DrawerWay", 43 Description = "The DrawerWay for CustomerEntity" 44 }, 45 new QueryArgument<StringGraphType> 46 { 47 Name = "EMail", 48 Description = "The EMail for CustomerEntity" 49 }, 50 new QueryArgument<StringGraphType> 51 { 52 Name = "Name_CN", 53 Description = "The Name_CN for CustomerEntity" 54 }, 55 new QueryArgument<StringGraphType> 56 { 57 Name = "Name_EN", 58 Description = "The Name_EN for CustomerEntity" 59 }, 60 new QueryArgument<StringGraphType> 61 { 62 Name = "Remark", 63 Description = "The Remark for CustomerEntity" 64 }, 65 new QueryArgument<StringGraphType> 66 { 67 Name = "Sex", 68 Description = "The Sex for CustomerEntity" 69 }, 70 new QueryArgument<StringGraphType> 71 { 72 Name = "WorkUnit", 73 Description = "The WorkUnit for CustomerEntity" 74 } 75 }, 76 resolve: context =>// 定义查询操作的执行 77 { 78 var customerContext = context.UserContext;// 获取上下文,可在此作用户验证操作 79 customers = repository.GetAll(); 80 var Guid = context.GetArgument<string>("Guid"); 81 customers = customers.Where(u => Guid == null || u.BirthDay == Guid); 82 var BirthDay = context.GetArgument<string>("BirthDay"); 83 customers = customers.Where(u => BirthDay == null || u.BirthDay == BirthDay); 84 var Code_CN = context.GetArgument<string>("Code_CN"); 85 customers = customers.Where(u => Code_CN == null || u.Code_CN == Code_CN); 86 var Code_EN = context.GetArgument<string>("Code_EN"); 87 customers = customers.Where(u => Code_EN == null || u.Code_EN == Code_EN); 88 var Country = context.GetArgument<string>("Country"); 89 customers = customers.Where(u => Country == null || u.Country == Country); 90 var DrawerWay = context.GetArgument<string>("DrawerWay"); 91 customers = customers.Where(u => DrawerWay == null || u.DrawerWay == DrawerWay); 92 var EMail = context.GetArgument<string>("EMail"); 93 customers = customers.Where(u => EMail == null || u.EMail == EMail); 94 var Name_CN = context.GetArgument<string>("Name_CN"); 95 customers = customers.Where(u => Name_CN == null || u.Name_CN == Name_CN); 96 var Name_EN = context.GetArgument<string>("Name_EN"); 97 customers = customers.Where(u => Name_EN == null || u.Name_EN == Name_EN); 98 var Remark = context.GetArgument<string>("Remark"); 99 customers = customers.Where(u => Remark == null || u.Remark == Remark); 100 var Sex = context.GetArgument<string>("Sex"); 101 customers = customers.Where(u => Sex == null || u.Sex == Sex); 102 var WorkUnit = context.GetArgument<string>("WorkUnit"); 103 customers = customers.Where(u => WorkUnit == null || u.WorkUnit == WorkUnit); 104 105 return customers; 106 }); 107 108 Field<CustomerEntityType>( 109 name: "AddCustomer", //注意这个名字,后边查询的时候需要对应 110 arguments: new QueryArguments //定义查询参数 111 { 112 new QueryArgument<StringGraphType> 113 { 114 Name = "Guid", 115 Description = "The Guid for the CustomerEntity" 116 }, 117 new QueryArgument<StringGraphType> 118 { 119 Name = "BirthDay", 120 Description = "The BirthDay for the CustomerEntity" 121 }, 122 new QueryArgument<StringGraphType> 123 { 124 Name = "Code_CN", 125 Description = "The Code_CN for the CustomerEntity" 126 }, 127 new QueryArgument<StringGraphType> 128 { 129 Name = "Code_EN", 130 Description = "The Code_EN for CustomerEntity" 131 }, 132 new QueryArgument<StringGraphType> 133 { 134 Name = "Country", 135 Description = "The Country for CustomerEntity" 136 }, 137 new QueryArgument<StringGraphType> 138 { 139 Name = "DrawerWay", 140 Description = "The DrawerWay for CustomerEntity" 141 }, 142 new QueryArgument<StringGraphType> 143 { 144 Name = "EMail", 145 Description = "The EMail for CustomerEntity" 146 }, 147 new QueryArgument<StringGraphType> 148 { 149 Name = "Name_CN", 150 Description = "The Name_CN for CustomerEntity" 151 }, 152 new QueryArgument<StringGraphType> 153 { 154 Name = "Name_EN", 155 Description = "The Name_EN for CustomerEntity" 156 }, 157 new QueryArgument<StringGraphType> 158 { 159 Name = "Remark", 160 Description = "The Remark for CustomerEntity" 161 }, 162 new QueryArgument<StringGraphType> 163 { 164 Name = "Sex", 165 Description = "The Sex for CustomerEntity" 166 }, 167 new QueryArgument<StringGraphType> 168 { 169 Name = "WorkUnit", 170 Description = "The WorkUnit for CustomerEntity" 171 } 172 }, 173 resolve: context =>// 定义查询操作的执行 174 { 175 string guid = context.GetArgument<string>("Guid"); 176 return repository.GetByID(guid); 177 }); 178 } 179 }
更新操作:
1 /// <summary> 2 /// GraphQL修改更新 3 /// </summary> 4 public class MutationAction : ObjectGraphType 5 { 6 private ICustomerRepository _repository = new CustomerRepository(); 7 IEnumerable<CustomerEntity> customers = null; 8 9 public MutationAction() 10 { 11 Field<StringGraphType>( 12 "run", 13 arguments: new QueryArguments(new QueryArgument<CustomerEntityType> { Name = "customer" }), 14 resolve: ctx => ctx.GetArgument<CustomerEntity>("customer").Guid); 15 } 16 }
5、定义GraphSchema模型
GraphSchema是GraphQL重中之重,它是所有操作的枢纽。
1 public class GraphSchema : Schema 2 { 3 public GraphSchema() 4 { 5 Query = new QueryAction(); 6 Mutation = new MutationAction(); 7 } 8 }
6、测试调用
测试一下查询操作,关键代码如下:
1 public async void QueryCustomers(string Code_CN, string Code_EN) 2 { 3 var queryStr = @"{customers(Code_CN:" + Code_CN + ",Code_EN:" + """ + Code_EN + """ + "){Code_CN Code_EN Name_CN Name_EN}}"; 4 var result = await execute.ExecuteAction(new GraphQLQuery { Query = queryStr, CustomerEntityContext = "Add Customer" }); 5 var data = result.Data; 6 Assert.IsNull(result.Errors?.Count); 7 }
这里你可以修改你的查询参数,无须修改API接口便可以达到目的。
修改更新接口的操作主要代码如下:
1 public async void CreateCustomer(string Code_CN, string Code_EN) 2 { 3 var queryStr = @"{query: mutation ($customer: UserInput!){AddCustomer($customer:$customer){Code_CN Code_EN Name_CN Name_EN}},variables:{customer:{Code_CN: " + Code_CN + @",Code_EN:" + Code_EN + @"}}}"; 4 5 var query = new GraphQLQuery 6 { 7 Query = "mutation ($customer: UserInput!){AddCustomer(customer:$customer){Code_CN Code_EN Name_CN Name_EN}}", 8 Variables = JObject.Parse("{customer:{"Code_CN": "" + Code_CN + "","Code_EN":" + Code_EN + "}}") 9 }; 10 var result = await execute.ExecuteAction(query); 11 Assert.IsNull(result.Errors.Count); 12 }
好了,以上就是我得初步总结和实践,后续会继续跟踪,欢迎纠错!!!