.NET利用Graphql的演示——新一代的API交互

打印 上一主题 下一主题

主题 811|帖子 811|积分 2433

Graphql是什么?先来一段AI给的回答:GraphQL是一种为API计划的查询语言,与REST相比,它提供了更高效、强盛和机动的方法来与数据交互。GraphQL由Facebook于2012年开发,并于2015年开源。其重要的优势在于能够答应客户端精确地指定他们需要的数据,从而避免了过分获取或数据不足的问题。重要特性

  • 精确获取需要的数据:

  • 单一端点:

  • 类型系统:

  • 查询与修改:

  • 实时数据(Subscription):
优势和范围优势:

  • 减少数据传输:只返回客户端哀求的数据。
  • 减少哀求数:多个数据需求可以在单一查询中办理。
  • 机动性高:客户端可以自由构造查询,无需服务器频仍更新API。
范围:

  • 复杂查询性能问题:如果不加限制地进行深度查询或大规模的数据嵌套,可能会对服务器性能造成影响。
  • 缓存计谋:相比于REST的URL级别缓存,GraphQL需要更复杂的缓存计谋来优化性能。
  • 学习曲线:对于开发者来说,需要学习新的查询语法及其底层实现。
 其他内容就不过多介绍了,大家感兴趣可以自行去搜刮有关理论或说明。接下来我直接提供实战入门演示。 以下开始正式演示正文:先创建一个webapi项目作为服务端和一个控制台项目作为客户端,用来测试利用。以及对应的引用包,如下图所示:
 新建Quries文件夹,用来存放查询利用的类和方法。以及新增一个测试用的类和string类型返回值的方法 Hello() 
在启动项或Program里面,添加Graphql服务,并添加Query的类型注册: 
 最后还要记得映射端点:
然后运行程序,例如我默认运行起来端口是5264,则打开url(根据自己情况更改url地点):http://localhost:5264/graphql/然后输入查询语句:query:{hello}就可以查出对应的返回内容。
客户端里面,创建graphql的客户端哀求,并输入查询的方法为hello的query语句,以及输出的结果,如下图所示。结果和上面的一样,只是我只输出data里面的数据,data里面的数据就是我们需要的结果。
 接着做个拓展演示,创建一个嵌套实体类,用来模拟多种情况:
 创建一个测试利用的服务,模拟具体查询业务利用。
 注册服务和接口以后,运行程序,并在graphql里面进行运行测试。当前测试的是输出全部字段。
 现在,例如我把子集合去掉不要,那查询出来也就不会带有子集合的任何内容:
 或者只需要指定的其他字段,删掉了描述、子集合的城市字段:
 同样的,把查询语句丢到客户端程序里面进行查询,也可以查出指定字段的内容:
 上面演示的是查询结果,也可以做增删改等其他操纵。在测试服务类新增一个业务操纵,模拟接收到参数以后进行了业务操纵,最终返回一个代表成功的数据。例如:
 新建一个Mutations文件夹,用来存放增删改操纵的类等。例如此处的测试利用的TestMutation.然后创建一个模拟传入参数进行操纵的方法,该方法返回上面服务类里面的测试方法。
 需要添加对修改有关操纵的注册:
 然后启动,做个测试。利用mutation语句进行操纵,操纵指定方法,方法里面指定参数和字段数据。可以看到服务端进入了前面预设的业务方法内,并且返回的true被客户端成功接收。
 在控制台客户端,也实行一下mutation操纵,也能够成功调用:
 以上是查询和修改操纵的例子,graphql还可以做数据推送和订阅,用于实现websocket的结果。新建一个subscriptions文件夹,用来存放全部的消息推送和订阅有关的界说类。例如TestSub,里面界说了一个推送方法OnTestPublish
 在前面的测试服务里面,新增ITopicEventSender事件接口的注入,以及新增一个方法,用来触发推送功能。并且推送的主题,利用刚才界说的OnTestPublish
 然后需要提供对推送服务的注册,以及持久化选择。
利用默认的持久化,该持久化选择不发起上生产。具体原因,我去AI一下:

  • 可扩展性问题:AddInMemorySubscriptions 存储订阅信息是在内存中进行的。这意味着订阅数据仅存在于单个进程中。如果你的应用程序需要在多个服务器实例之间进行扩展,每个实例的内存中都会有独立的订阅状态,从而导致状态不同等。因此,在大型应用或高负载环境中,这种方法不能很好地扩展。
  • 持久性缺失:利用内存存储的另一个重要问题是数据的持久性。服务器重启或发生故障时,全部在内存中的订阅数据将丢失。这对于生产环境来说是不可接受的,由于需要保证服务的稳定性和数据的持久性。
  • 资源利用效率:随着订阅数量的增加,内存的利用量也会随之上升。在内存资源有限的环境中,这可能会影相应用程序的团体性能和相应速度。
  • 故障恢复:在内存中的订阅管理缺乏有效的故障恢复机制。如果系统崩溃或需要进行维护,恢复订阅状态将非常困难,可能需要从客户端重新创建订阅。
为了办理这些问题,生产环境中通常发起利用持久化和可扩展的订阅存储方案,比如基于 Redis 的 AddRedisSubscriptions 方法。大佬们感兴趣可以自己去拓展下。 现在缺少一个触发条件,由于咱们创建的是webapi项目,自带控制器,那我把控制器做个改造,通过swagger来调用进行触发数据推送,直接在哀求里面,调用推送方法:
 最后,由于推送利用了websocket,所以也需要添加对websocket的注册:
 然后启动程序,利用subscription进行订阅onTestPublish主题消息。运行以后,会不绝监听,除非我们取消监听。
 打开swagger,直接调用并测试,可以看到面板接收到了测试推送的数据。
 客户端要实现订阅,需要做一些改动。订阅的事件是字符串类型,所以需要创建一个字符串类型的属性,用来接收数据:
 然后客户端创建时间,需要利用websocket端点。然后再创建订阅语句
 接下来是订阅的具体实现演示:
 答应,并通过swagger调用两次测试,都可以被监听到。
 同时,之前打开的graphql演示面板,也可以看到能够收到后续消息,说明支持多客户端接收,符合websocket的推送结果。
 有关实现的核心代码。服务端注册有关:
  1. // 添加GraphQL服务
  2. builder.Services
  3.      .AddGraphQLServer()
  4.      .AddQueryType<TestQuery>()
  5.      .AddMutationType<TestMutation>()
  6.      .AddSubscriptionType<TestSub>()
  7.      .AddInMemorySubscriptions(); // 默认消息持久化(生产情况建议更换)
  8. var app = builder.Build();
  9. app.UseWebSockets();
  10. // 映射GraphQL端点
  11. app.MapGraphQL();
复制代码
 
 客户端实现:
  1. var option = new GraphQLHttpClientOptions
  2. {
  3.      EndPoint = new Uri("http://localhost:5264/graphql"),
  4.      // 设置 WebSocket 端点以支持订阅
  5.      WebSocketEndPoint = new Uri("ws://localhost:5264/graphql")
  6. };
  7. using var client = new GraphQLHttpClient(/*"http://localhost:5264/graphql"*/ option , new NewtonsoftJsonSerializer());
  8. //            var request = new GraphQLRequest
  9. //            {
  10. //                Query = @"mutation{
  11. //  otherOperation(info:{address:""龙岗区宝龙街道"",city:""大大大深圳"",phone:""10100011""})
  12. //}"
  13. //            };
  14. //            var response = await client.SendQueryAsync<object>(request);
  15. //            Console.WriteLine(response.Data);
  16. // 定义订阅请求
  17. var subscriptionRequest = new GraphQLRequest
  18. {
  19.      Query = @"
  20.      subscription {
  21.          onTestPublish
  22.      }"
  23. };
  24. // 创建订阅流
  25. var subscriptionStream = client.CreateSubscriptionStream<OnTestPublishResponse>(subscriptionRequest);
  26. // 订阅消息流
  27. var subscription = subscriptionStream.Subscribe(
  28.      response =>
  29.      {
  30.          if (response.Errors != null)
  31.          {
  32.              Console.WriteLine("Error occurred: " + response.Errors);
  33.          }
  34.          else
  35.          {
  36.              Console.WriteLine($"Received message: {response.Data.OnTestPublish}");
  37.          }
  38.      },
  39.      error => Console.WriteLine($"Subscription error: {error.Message}"),
  40.      () => Console.WriteLine("Subscription completed."));
  41. // 模拟其他逻辑(例如,在某个时刻取消订阅,这儿通过输入任意按键触发取消和释放)
  42. Console.WriteLine("Press any key to exit...");
  43. Console.ReadKey();
  44. // 取消订阅并关闭 WebSocket 连接
  45. subscription.Dispose();
  46. client.Dispose();
复制代码
 
 如果需要我本地演示的代码项目,可以在本人公众号【Dotnet Dancer】回复: 代码演示  即可获取开源项目地点。如果需要其他咨询或互助,可V:WeskyNet001
 
如果以上内容对你有资助,接待大佬们点赞、关注公众号或转发。谢谢大家!
 
 
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连密封材料

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表