先简单对比以下GraphQL和WebAPI:
GraphQL和Web API(如RESTful API)是用于构建和提供Web服务的不同技术。

  1. 数据获取方式:
  • Web API:通常使用RESTful API,客户端通过发送HTTP请求(如GET、POST、PUT、DELETE)来获取特定的数据。每个请求通常返回一个固定的数据结构,包含在响应的主体中。
  • GraphQL:客户端可以使用GraphQL查询语言来精确指定需要的数据。客户端发送一个GraphQL查询请求,服务器根据查询的结构和字段来返回相应的数据。
  1. 数据获取效率:
  • Web API:每个请求返回的数据通常是预定义的,无论客户端需要的数据量大小,服务器都会返回相同的数据结构。这可能导致客户端获取到不必要的数据,或者需要发起多个请求来获取所需数据。
  • GraphQL:客户端可以精确指定需要的数据,避免了不必要的数据传输。客户端可以在一个请求中获取多个资源,并且可以根据需要进行字段选择、过滤、排序等操作,从而提高数据获取效率。
  1. 版本管理:
  • Web API:通常使用URL版本控制或者自定义的HTTP头来管理API的版本。当API发生变化时,可能需要创建新的URL或者HTTP头来支持新的版本。
  • GraphQL:GraphQL中没有显式的版本控制机制,而是通过向现有的类型和字段添加新的字段来扩展现有的API。这样可以避免创建多个不同版本的API。
  1. 客户端开发体验:
  • 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的更多相关文章

  1. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

  2. GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。

    1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...

  3. 除非你是BAT,前端开发中最好少造轮子

    站在前人的肩膀上 HTML.CSS.JavaScript是前端的根基,这是无可否认的事实.正如一辆车当然都是由一堆钢板和螺钉组成的,但是现在还有人拎着个锤子敲敲打打的造车吗?李书福说过,“汽车不过是四 ...

  4. Meteva——让预报检验不再重复造轮子

    更多精彩,请点击上方蓝字关注我们! 检验是什么?****预报准确率的客观表达 说到天气预报,你最先会想到什么? 早上听了预报,带了一天伞却没下一滴雨的调侃? 还是 "蓝天白云晴空万里突然暴风 ...

  5. 54 个官方 Spring Boot Starters 出炉!别再重复造轮子了…….

    在之前的文章,栈长介绍了 Spring Boot Starters,不清楚的可以点击链接进去看下. 前段时间 Spring Boot 2.4.0 也发布了,本文栈长再详细总结下最新的 Spring B ...

  6. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  7. 【疯狂造轮子-iOS】JSON转Model系列之一

    [疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...

  8. h5engine造轮子

    基于学习的造轮子,这是一个最简单,最基础的一个canvas渲染引擎,通过这个引擎架构,可以很快的学习canvas渲染模式! 地址:https://github.com/RichLiu1023/h5en ...

  9. 我为什么还要造轮子?欠踹?Monk.UI表单美化插件诞生记!

    背景 目前市场上有很多表单美化的UI,做的都挺不错,但是他们都有一个共同点,那就是90%以上都是前端工程师开发的,导致我们引入这些UI的时候,很难和程序绑定.所以作为程序员的我,下了一个决定!我要自己 ...

  10. 「iOS造轮子」之UIButton 用Block响应事件

    俗语说 一个不懒的程序员不是好程序员 造轮子,也只是为了以后更好的coding. coding,简易明了的代码更是所有程序员都希望看到的 无论是看自己的代码,还是接手别人的代码 都希望一看都知道这代码 ...

随机推荐

  1. JS逆向实战19——通杀webpack逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 网站 aHR0cHM6Ly ...

  2. 【笔试实战】LeetCode题单刷题-编程基础 0 到 1【一】

    1768. 交替合并字符串 题目链接 1768. 交替合并字符串 题目描述 给你两个字符串 word1 和 word2 .请你从 word1 开始,通过交替添加字母来合并字符串.如果一个字符串比另一个 ...

  3. 2 opencv-python核心库模块core

    core模块定义了opencv中的基础数据结构和基础运算,是整个库的核心模块.而mat数据结构是opencv中最重要的数据结构,是opencv中图像最常用的存储格式. 1 基本数据结构 opencv的 ...

  4. animation动画+关键帧实现轮播图效果(再次学习)!

    再次遇到要实现轮播图效果的时候,发现还是不怎么会,因为对js还没有熟练使用,只希望使用h5和css3实现效果 虽然之前已经学习了一遍了,但是还是不熟练,再次学习一下了 这次的可作为套板使用,无序列表为 ...

  5. java学习中的一些总结

    最近java要考试了,在复习的时候就发现什么成员变量,成员函数,静态,非静态,里面的一些东西都乱七八糟的(其实是我太菜了,没有理解透彻) 我查了很多相关的资料,网上很多大佬总结的非常好 知识点一 成员 ...

  6. gin 接口开发 - 用户输入自动 TrimSpace

    最近在思考一个问题,针对用户的输入,能不能快速校验? 比方说下面的 struct,大家用过 gin 的就知道,支持指定某个字段为 required,用户如果不输入,就检验不通过. type Login ...

  7. 【WebGL系列-02】创建program上下文

    WebGL程序program对象的创建 program对象由顶点着色器对象和片元着色器对象构成,因此,创建program对象包含了两部分,一个是着色器对象的创建,一个是program对象的创建. 总体 ...

  8. 01-jQuery的基本结构

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Cesium Billboard加载Gif图片

    https://blog.csdn.net/xietao20/article/details/109404491

  10. 使用logrotate定期切割nginx日志

    前言 默认情况下,nginx的日志都会写到access.log文件中,访问流量大的话,日志文件很快就会膨胀到几十G,不方便分析处理,也占用硬盘空间.借助linux自带的logrotate工具可以很方便 ...