造轮子之集成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,简易明了的代码更是所有程序员都希望看到的 无论是看自己的代码,还是接手别人的代码 都希望一看都知道这代码 ...
随机推荐
- Spring Cloud Gateway编码实现任意地址跳转
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 作为<Spring Cloud Gat ...
- node使用jsonwebtoken生成token与验证是否过期
场景 我们可以使用 cookie,session,token 来做鉴权. 下面我们来看一下, 如何使用 token 来做鉴权 jwt.sign 的简单介绍 npm install jsonwebtok ...
- CF546E Soldier and Traveling 题解
CF546E Soldier and Traveling 英文原题: 当然Luogu有中文翻译 对于这种类型的题目,又是增加,又是减少的,我们可以使用网络流进行转化. 说句废话: 网络流这个东西,趣味 ...
- pandas: dataframe转字典,并设置key
解决方案 res = df_by_monthly.set_index('recruit_resign_month').T.to_dict('list') print(res) 上述代码是转为列表形式 ...
- 好用工具: windows terminal
直接在微软商店搜索该软件即可,本文介绍无法使用微软商店的情况. 解题思路 当我们无法下载某个软件时,可直接去Github中寻找该项目,知道该软件资源并下载. 下载地址 https://github.c ...
- 图加速数据湖分析-GeaFlow和Apache Hudi集成
表模型现状与问题 关系模型自1970年由埃德加·科德提出来以后被广泛应用于数据库和数仓等数据处理系统的数据建模.关系模型以表作为基本的数据结构来定义数据模型,表为二维数据结构,本身缺乏关系的表达能力, ...
- Web通用漏洞--文件包含
Web通用漏洞--文件包含 文件包含原理 在项目开发过程中,开发人员通常会将重复使用的函数写入单个文件中,在使用该类函数时,直接调用文件即可,无需重新编写,这种调用文件的过程成为文件包含.在文件包含过 ...
- [Lua][Love Engine] 打砖块游戏实现过程与知识点
本文旨在根据LOVE2D官方文档和教程实现打砖块的游戏,记录部分实现过程和重要知识点 目标摧毁所有砖块 玩家控制球拍左右滑动反弹小球 小球摧毁砖块 小球保持在屏幕内 小球碰到屏幕底部,GAME OVE ...
- django配置swagger自动生成接口文档以及自定义参数设置
首先安装swagger所用的包 pip install drf-yasg 然后再settings.py 中注册app 接口采用的token认证,在settings.py配置认证方式 SWAGGER_S ...
- 反汇编ARM程序的技术靠谱吗?——揭秘ARM架构二进制程序的反汇编技术现状
本文系原创,转载请说明出处 Please Subscribe Wechat Official Account:信安科研人,获取更多的原创安全资讯 参考发表在2020年软工顶会ISSTA的论文&l ...