造轮子之集成GraphQL
先简单对比以下GraphQL和WebAPI:
GraphQL和Web API(如RESTful API)是用于构建和提供Web服务的不同技术。
- 数据获取方式:
- Web API:通常使用RESTful API,客户端通过发送HTTP请求(如GET、POST、PUT、DELETE)来获取特定的数据。每个请求通常返回一个固定的数据结构,包含在响应的主体中。
- GraphQL:客户端可以使用GraphQL查询语言来精确指定需要的数据。客户端发送一个GraphQL查询请求,服务器根据查询的结构和字段来返回相应的数据。
- 数据获取效率:
- Web API:每个请求返回的数据通常是预定义的,无论客户端需要的数据量大小,服务器都会返回相同的数据结构。这可能导致客户端获取到不必要的数据,或者需要发起多个请求来获取所需数据。
- GraphQL:客户端可以精确指定需要的数据,避免了不必要的数据传输。客户端可以在一个请求中获取多个资源,并且可以根据需要进行字段选择、过滤、排序等操作,从而提高数据获取效率。
- 版本管理:
- Web API:通常使用URL版本控制或者自定义的HTTP头来管理API的版本。当API发生变化时,可能需要创建新的URL或者HTTP头来支持新的版本。
- GraphQL:GraphQL中没有显式的版本控制机制,而是通过向现有的类型和字段添加新的字段来扩展现有的API。这样可以避免创建多个不同版本的API。
- 客户端开发体验:
- Web API:客户端需要根据API的文档来构造请求和解析响应。客户端需要手动处理不同的API端点和数据结构。
- GraphQL:客户端可以使用GraphQL的强类型系统和自动生成的代码工具来进行开发。客户端可以根据GraphQL的模式自动生成类型定义和查询代码,提供了更好的开发体验和类型安全性。
在前面我们基础框架是基于WebAPI(REST FUL API)的模式去开发接口的,所有的响应数据都需要定义一个DTO结构,但是有些场景可能只需要某些字段,而后端又懒得定义新数据接口对接,这就会导致客户端获取到不必要的数据。在这种情况下,使用GraphQL就可以有较好的体验。
那么,在我们现有写好的Service中,如何快速集成GraphQL又无需复杂编码工作呢。这就是我们接下来要实现的了。
HotChocolate.AspNetCore
HotChocolate.AspNetCore是.NET一个老牌的GraphQL实现库,它可以让我们很快速的实现一个GraphQL Server。
安装HotChocolate.AspNetCore的nuget,在Program中添加代码
builder.Services.AddGraphQLServer()
app.MapGraphQL();
这样就完成一个GraphQLServer的集成。
启动程序,访问https://localhost:7080/graphql/ 可以看到集成的界面。可以使用这个界面操作测试我们的graphql查询。
实现QueryType
接下来实现一个基础的QueryType,用于扩展查询。
using HotChocolate.Authorization;
namespace Wheel.Graphql
{
[Authorize]
public class Query : IQuery
{
}
[InterfaceType]
public interface IQuery
{
}
}
在AddGraphQLServer()后面添加代码
builder.Services.AddGraphQLServer()
.AddQueryType<Query>()
;
使用ExtendObjectType扩展Query类,方便接口拆分。
public interface IQueryExtendObjectType
{
}
[ExtendObjectType(typeof(IQuery))]
public class SampleQuery : IQueryExtendObjectType
{
public List<string> Sample()
{
return new List<string> { "sample1", "sample2" };
}
}
[ExtendObjectType(typeof(IQuery))]
public class Sample2Query : IQueryExtendObjectType
{
public string Sample2(string id)
{
return id;
}
}
这里创建一个IQueryExtendObjectType空接口,用于获取所有需要扩展的QueryAPI
约定所有扩展的Query需要继承IQueryExtendObjectType接口,并加上ExtendObjectType特性标签。
封装AddGraphQLServer方法:
using HotChocolate.Execution.Configuration;
using System.Reflection;
namespace Wheel.Graphql
{
public static class GraphQLExtensions
{
public static IRequestExecutorBuilder AddWheelGraphQL(this IServiceCollection services)
{
var result = services.AddGraphQLServer()
.AddQueryType<Query>()
;
var abs = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll")
.Where(x => !x.Contains("Microsoft.") && !x.Contains("System."))
.Select(x => Assembly.Load(AssemblyName.GetAssemblyName(x))).ToArray();
var types = abs.SelectMany(ab => ab.GetTypes()
.Where(t => typeof(IQueryExtendObjectType).IsAssignableFrom(t) && typeof(IQueryExtendObjectType) != t));
if (types.Any())
{
result = result.AddTypes(types.ToArray());
}
return result;
}
}
}
遍历所有IQueryExtendObjectType并加入GraphQLServer。
启动项目访问https://localhost:7080/graphql/
可以看到SchemaDefinition自动生成了我们的两个查询。
添加授权
安装HotChocolate.AspNetCore.Authorization的Nuget包。
在services.AddGraphQLServer()后面添加代码.AddAuthorization()
using HotChocolate.Execution.Configuration;
using System.Reflection;
namespace Wheel.Graphql
{
public static class GraphQLExtensions
{
public static IRequestExecutorBuilder AddWheelGraphQL(this IServiceCollection services)
{
var result = services.AddGraphQLServer()
.AddAuthorization()
.AddQueryType<Query>()
;
var abs = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll")
.Where(x => !x.Contains("Microsoft.") && !x.Contains("System."))
.Select(x => Assembly.Load(AssemblyName.GetAssemblyName(x))).ToArray();
var types = abs.SelectMany(ab => ab.GetTypes()
.Where(t => typeof(IQueryExtendObjectType).IsAssignableFrom(t) && typeof(IQueryExtendObjectType) != t));
if (types.Any())
{
result = result.AddTypes(types.ToArray());
}
return result;
}
}
}
未登录前执行查询,可以看到响应Error。
获取一个token之后配置一下:
再次请求,可以看到正常查询。
集成现有Service
改造一下SampleQuery
[ExtendObjectType(typeof(IQuery))]
public class SampleQuery : IQueryExtendObjectType
{
public async Task<List<GetAllPermissionDto>> Sample([Service] IPermissionManageAppService permissionManageAppService)
{
var result = await permissionManageAppService.GetPermission();
return result.Data;
}
}
打开https://localhost:7080/graphql/ 执行查询,可以看到正常返回。
当我们需要过滤不查询某些字段时,只需要修改Query查询格式。
分页查询,添加一下User的分页查询代码。
public class SampleQuery : IQueryExtendObjectType
{
public async Task<List<GetAllPermissionDto>> Sample([Service] IPermissionManageAppService permissionManageAppService)
{
var result = await permissionManageAppService.GetPermission();
return result.Data;
}
public async Task<Page<UserDto>> SampleUser(UserPageRequest pageRequest, [Service] IUserManageAppService userManageAppService)
{
var result = await userManageAppService.GetUserPageList(pageRequest);
return result;
}
}
测试:
可以看到,很简单就可以把现有的API转换成GraphQL。只不过一些排序分页逻辑我们没有采用GraphQL的方式,而是使用我们自己的WebApi分页查询的模式。
轮子仓库地址https://github.com/Wheel-Framework/Wheel
欢迎进群催更。

造轮子之集成GraphQL的更多相关文章
- 避免重复造轮子的UI自动化测试框架开发
一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...
- GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。
1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...
- 除非你是BAT,前端开发中最好少造轮子
站在前人的肩膀上 HTML.CSS.JavaScript是前端的根基,这是无可否认的事实.正如一辆车当然都是由一堆钢板和螺钉组成的,但是现在还有人拎着个锤子敲敲打打的造车吗?李书福说过,“汽车不过是四 ...
- Meteva——让预报检验不再重复造轮子
更多精彩,请点击上方蓝字关注我们! 检验是什么?****预报准确率的客观表达 说到天气预报,你最先会想到什么? 早上听了预报,带了一天伞却没下一滴雨的调侃? 还是 "蓝天白云晴空万里突然暴风 ...
- 54 个官方 Spring Boot Starters 出炉!别再重复造轮子了…….
在之前的文章,栈长介绍了 Spring Boot Starters,不清楚的可以点击链接进去看下. 前段时间 Spring Boot 2.4.0 也发布了,本文栈长再详细总结下最新的 Spring B ...
- 【疯狂造轮子-iOS】JSON转Model系列之二
[疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- h5engine造轮子
基于学习的造轮子,这是一个最简单,最基础的一个canvas渲染引擎,通过这个引擎架构,可以很快的学习canvas渲染模式! 地址:https://github.com/RichLiu1023/h5en ...
- 我为什么还要造轮子?欠踹?Monk.UI表单美化插件诞生记!
背景 目前市场上有很多表单美化的UI,做的都挺不错,但是他们都有一个共同点,那就是90%以上都是前端工程师开发的,导致我们引入这些UI的时候,很难和程序绑定.所以作为程序员的我,下了一个决定!我要自己 ...
- 「iOS造轮子」之UIButton 用Block响应事件
俗语说 一个不懒的程序员不是好程序员 造轮子,也只是为了以后更好的coding. coding,简易明了的代码更是所有程序员都希望看到的 无论是看自己的代码,还是接手别人的代码 都希望一看都知道这代码 ...
随机推荐
- 一份保姆级的Stable Diffusion部署教程,开启你的炼丹之路
市面上有很多可以被用于AI绘画的应用,例如DALL-E.Midjourney.NovelAI等,他们的大部分都依托云端服务器运行,一部分还需要支付会员费用来购买更多出图的额度.在2022年8月,一款叫 ...
- Unity的Console的控制类LogEntries:深入解析与实用案例
使用Unity Console窗口的LogEntries私有类实现自定义日志系统 在Unity开发过程中,我们经常需要使用Console窗口来查看程序运行时的日志信息.Unity内置的日志系统提供了基 ...
- 聊一聊Java中的Steam流
1 引言 在我们的日常编程任务中,对于集合的制造和处理是必不可少的.当我们需要对于集合进行分组或查找的操作时,需要用迭代器对于集合进行操作,而当我们需要处理的数据量很大的时候,为了提高性能,就需要使用 ...
- CVPR 2023 | RCF:完全无监督的视频物体分割
TLDR: 视频分割一直是重标注的一个task,这篇CVPR 2023文章研究了完全不需要标注的视频物体分割.仅使用ResNet,RCF模型在DAVIS16/STv2/FBMS59上提升了7/9/5% ...
- 教师节专题:AI互动课来了,即构方案助推在线教育创新升级
打开热门综艺,乘风破浪的姐姐们告诉你"用瓜瓜龙英语给孩子启蒙":走出家门,电梯口.公交站的大幅广告跟你说"2-8岁上斑马". 如果说去年的AI互动课还是浮于媒体 ...
- 2023ccpc大学生程序设计竞赛-wh
对于大一的我,只听说线下大型比赛,而第一次参加也必然心情激动,生为大一,由于没有参赛经历,所有不知道参赛技巧,所以三个人像个无头苍蝇一样,跟着榜单做,我作为写码的,其他两名队友负责思路和想法,第一道签 ...
- sshpass快速登录远程主机:s2
#!/bin/bash passwd= if [ $# -ne 1 ] then echo "$0 [31|37|61]" fi if command -v sshpass the ...
- 看element源码学到的小技巧
中午无休的时候有点无聊, 看了一下昨天clone 的 element-ui 源码, 发现很多优雅之处, 记录一下让我直接用到项目中的一个点 那就是绝对定位的元素放到body 里面的 同级.这么做的好处 ...
- G-channel 实现低光图像增强
G-channel 之前研究低光图像增强时,看到一篇博客,里面介绍了一种方法,没有说明出处,也没有说明方法的名字,这里暂时叫做 G-channel 算法. 博客地址:低照度图像增强(附步骤及源码)_低 ...
- 牛客小白月赛65 D题 题解
原题链接 题意描述 一共有两堆石子,第一堆有 \(a\) 个,第二堆有 \(b\) 个,牛牛和牛妹轮流取石子,牛牛先手,每次取石子的时候只能从以下 \(2\) 种方案种挑一种来取(对于选择的方案数必须 ...