众所周知RESTful API是目前最流行的软件架构风格之一,它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

RESTful的优越性是毋庸置疑的,不过GraphQL也可以作为一种补充,让你的服务既支持RESTful的http调用,也容许客户端通过GraphQL支持的声明式语法调用服务。

本篇文章并不想对比RESTful和GraphQL孰轻孰重,或者那种方式更好,相关比较可以参考GraphQL的前世今生。本文旨在介绍如何在ASP.NET Core应用中引入GraphQL,让你的应用既支持RESTFul,也能支持GraphQL。

Web应用程序是如何工作的

如果说一个Service能够提供一个功能,那么我们就可以给Service一个输入,从而得到一个输出。

如果将若干个Service组合在一起形成一个应用程序,那么这个应用程序就可以提供若干个能力,当一个框架分别就输入和输出进行统一的约定和规范时,也就是人们常说的SOAP,RESTful等技术。

对于RESTful来说,输入就是Http request,输出是一个json格式的字符串。而Web应用程序框架在做什么?根据某个输入(request),找到对应的controller, 击中合适的action,同时将Request绑定为action方法的参数,最后将结果格式化为json字符串并输出。

GraphQL就是跟Web框架同一级别的技术,只不过输入(input)不再是Http request,而是GraphQL特有的语法结构,输出仍然为json字符串。

GraphQL能够做些什么

既然GraphQL是一种可以代替RESTful的技术,那么你一定很想知道他是怎么做到的。 如果能用一句话总结那就是: GraphQL是一种API资源的查询语言。GraphQL通过下面的三种类型来满足用户的需求:

1. 查询

我们都知道用户的请求可以分为两类:Query和Command,Query用于查询资源,调用一次和多次都不会影响资源的状态,一个简单的查询如下:

query {
hero {
id
name
}
}

上面的查询语言可以理解为:查询hero资源的"id"和"name“属性

2. mutation

所谓mutation就是Command,意味着该用户请求能够改变服务端的状态,一个简单的mutation如下:

mutation ($human:HumanInput!) {
createHuman(human: $human) {
id
name
}
}
variables: {
"human": {
"name": "Boba Fett",
"homePlanet": "Kamino"
}
}

上面的mutation可以理解为创建一个humman对象,输入对象是一个$human变量,最后把创建对象的`”id"和"name"属性查询出来。可以看出mutation一般都要配合一个变量使用,变量需要在"variables"中单独定义。

3. Subscriptions

Subscriptions用于提供类似websocket的功能,GraphQL Server是一个实现了Apollo GraphQL订阅协议的.NET Core服务器. 下面的例子需要同时打开两个浏览器窗口:

Subscription用户订阅聊天消息:

subscription MessageAdded {
messageAdded {
from { id displayName }
content
}
}

Mutation用户添加聊天内容:

mutation AddMessage($message: MessageInputType!) {
addMessage(message: $message) {
from {
id
displayName
}
content
}
} variables:
{
"message": {
"content": "Message",
"fromId": "1"
}
}

GraphQL是如何实现的

我在用每一个开源框架或者类库时都习惯于先浏览源码,了解整个源码的大概结构和实现。下面的过程以一个简单的查询为例,分析GraphQL的实现原理:

{
query test {
user{
age
}
}
}

通过graphQL browser IDE发送请求:



GrpahQL处理的整个过程如下:

1.客户端将上面的GraphQL query通过http发送到服务端
curl 'http://localhost:5000/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: http://localhost:5000' --data-binary '{"query":"# Write your query or mutation here\nquery test{\n  user{\n    age\n  }\n}\n"}' --compressed
2. 整个Request以json的格式发送到了服务端,服务端将Request反序列化为GraphQLRequest类型:
public class GraphQLRequest
{
[JsonProperty("query")]
public string Query { get; set; } [JsonProperty("variables")]
public JObject Variables { get; set; } [JsonProperty("operationName")]
public string OperationName { get; set; } public Inputs GetInputs()
{
return GraphQLRequest.GetInputs(this.Variables);
}
}

针对上面的例子,实际上只有string Query属性被反序列化为”"# Write your query or mutation here\nquery test{\n user{\n age\n }\n}\n"“

3.服务端解析Query,解析Query的过程是一个语法分析的过程,通过Paser将Query解析为AST:
    var source = new Source(body);
var result = _parser.Parse(source);

Parse后的结果是一个Document类:

 public class Document : AbstractNode
{
public string OriginalQuery { get; set; }
public Operations Operations { get; }
public Fragments Fragments { get; }
}

本例的Query将会被解析为一个Operations,一个Operations将包含若干个有层次结构的Operation,解析Query的目的是为了知道客户端要查询user.Age这个属性。

4.有了一个Parse后的Document,接下来的工作将有DocumentExecuter来完成,DocumentExecuter定义了整个调用服务端资源的流程:
public async Task<ExecutionResult> ExecuteAsync(ExecutionOptions options)
{
//1. 打印开始时间
//2. Parse Document
//3. 验证Document是否是一个合法的GrapQL语法请求
//4. 在流程的各个阶段执行Listener,用于在不同的时机切入代码,类似于ASP.NET Core中的Filter
//5. 选择合适的执行策略
//6. 执行服务端资源
//7. 输出Response
}

以上就是GraphQL在.NET Core中的实现原理分析,下一篇将通过一个hello world级别的例子演示如何让你的ASP.NET应用程序支持GraphQL.

让ASP.NET Core支持GraphQL之-GraphQL的实现原理的更多相关文章

  1. 使用ASP.NET Core支持GraphQL -- 较为原始的方法

    GraphQL简介 下面是GraphQL的定义: GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述 ...

  2. 使用ASP.NET Core支持GraphQL( restful 配套)

    https://github.com/graphql-dotnet https://github.com/graphql GraphQL简介 官网:https://graphql.cn/code/ 下 ...

  3. asp dotnet core 支持客户端上传文件

    本文告诉大家如何在 asp dotnet core 支持客户端上传文件 新建一个 asp dotnet core 程序,创建一个新的类,用于给客户端上传文件的信息 public class Kanaj ...

  4. ASP.NET Core 中文文档 第三章 原理(7)配置

    原文:Configuration 作者:Steve Smith.Daniel Roth 翻译:刘怡(AlexLEWIS) 校对:孟帅洋(书缘) ASP.NET Core 支持多种配置选项.应用程序配置 ...

  5. ASP.NET Core 中文文档 第三章 原理(11)在多个环境中工作

    原文: Working with Multiple Environments 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core 介绍了支持在多个环境中管 ...

  6. ASP.NET Core 中文文档 第三章 原理(16).NET开放Web接口(OWIN)

    原文:Open Web Interface for .NET (OWIN) 作者:Steve Smith. Rick Anderson 翻译:谢炀(kiler398) 校对:孟帅洋(书缘) ASP.N ...

  7. ASP.NET Core 中文文档 第三章 原理(1)应用程序启动

    原文:Application Startup 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:谢炀(kiler398).许登洋(Seay) ASP.NET Core 为你的应用程 ...

  8. ASP.NET Core 中文文档 第三章 原理(2)中间件

    原文:Middleware 作者:Steve Smith.Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:许登洋(Seay) 章节: 什么是中间件 用 IApplicationBu ...

  9. ASP.NET Core 中文文档 第三章 原理(3)静态文件处理

    原文:Working with Static Files 作者:Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:谢炀(kiler398).许登洋(Seay).孟帅洋(书缘) 静态文 ...

随机推荐

  1. nsq源码阅读笔记之nsqd(一)——nsqd的配置解析和初始化

    配置解析 nsqd的主函数位于apps/nsqd.go中的main函数 首先main函数调用nsqFlagset和Parse进行命令行参数集初始化, 然后判断version参数是否存在,若存在,则打印 ...

  2. 【莫比乌斯反演】BZOJ3309 DZY Loves Math

    Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b, ...

  3. resteasy简单实例

    1.建一个maven web项目 新建一个maven项目,next,第一个框不要勾选 选择maven-archetype-webapp,建一个web项目 键入项目组织id与项目id 一般此时搭建的只是 ...

  4. Linux文件系统选择

    通过综合使用多种标准文件系统Benchmarks对Ext3, Ext4, Reiserfs, XFS, JFS, Reiser4的性能测试对比,对不同应用选择合适的文件系统给出以下方案,供大家参考.文 ...

  5. Linux下可以ping ip地址但无法ping域名解决方法

    分析:当前系统无法解决域名至ip地址故障. 步骤阅读 2 三:解决过程: 1.分析dns故障: 2.物理机可以ping 地址,但无法ping域名: 3.检查/etc/resolv.conf: 注: ( ...

  6. 开源方案搭建可离线的精美矢量切片地图服务-2.PostGIS+GeoServer矢量切片

    项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...

  7. Tomcat启动失败的几种解决办法

    1.重复映射 用Eclipse开发,新建了的servlet会有一个url-pattern声明: 这样就不需要在web.xml中添加映射,如果在web.xml中添加了这样一段: <servlet& ...

  8. java自动化-数据驱动juint演示,上篇

    本文旨在帮助读者介绍,一般的全自动化代码接口,并简单介绍如何使用数据驱动来实现简单的自动化 在经过上述几个博客介绍后,相信读者对自动启动执行一个java编译过的class有了一定了解,也完全有能力去执 ...

  9. 腾讯云centos服务器不能登录的解决过程

    在腾讯云上申请了一个centos服务器,最基础的配置,1 核 1 GB 1 Mbps,50G硬盘,主要用来测试程序,练手用.在上面配置了一个mysql数据库,一直使用都没什么问题. 1 问题描述 过了 ...

  10. Windows核心编程第二章,字符串的表示以及宽窄字符的转换

    目录 Windows核心编程,字符串的表示以及宽窄字符的转换 1.字符集 1.1.双字节字符集DBCS 1.2 Unicode字符集 1.3 UTF-8编码 1.4 UTF - 32编码. 1.5 U ...