让ASP.NET Core支持GraphQL之-GraphQL的实现原理

众所周知RESTful API是目前最流行的软件架构风格之一,它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
RESTful的优越性是毋庸置疑的,不过GraphQL也可以作为一种补充,让你的服务既支持RESTful的http调用,也容许客户端通过GraphQL支持的声明式语法调用服务。
本篇文章并不想对比RESTful和GraphQL孰轻孰重,或者那种方式更好,相关比较可以参考GraphQL的前世今生。本文旨在介绍如何在ASP.NET Core应用中引入GraphQL,让你的应用既支持RESTFul,也能支持GraphQL。


Web应用程序是如何工作的

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

640?wx_fmt=png

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

640?wx_fmt=png

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

640?wx_fmt=png

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

640?wx_fmt=png

GraphQL能够做些什么

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

1. 查询

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

query {hero {idname}
}

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

2. mutation

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

mutation ($human:HumanInput!) {createHuman(human: $human) {idname}
}
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 {iddisplayName}content}
}variables:
{"message": {"content": "Message","fromId": "1"}
}


GraphQL是如何实现的

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

{query test {user{age}}
}

通过graphQL browser IDE发送请求:GrpahQL处理的整个过程如下:

640?wx_fmt=png

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.

原文地址:https://www.cnblogs.com/xiandnc/p/10398505.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com
640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[2021-09-02 contest]CF1251C,可达性统计(bitset优化dp),Boomerang Tournament(状压dp),小蓝的好友(mrx)(treap平衡树)

文章目录CF1251C Minimize The Integeracwing164&#xff1a;可达性统计Facebook Hacker Cup 2016 Round 1 Boomerang Tournament[Zjoi2012]小蓝的好友(mrx)CF1251C Minimize The Integer ………………… 给你一个大整数aaa&#xff0c;它由nnn位数字&#xff0c;也可能有前导…

Entity Framework 的一些性能建议

点击上方蓝字关注“汪宇杰博客”这是一篇我在2012年写的老文章&#xff0c;至今适用&#xff08;没错&#xff0c;我说的就是适用于EF Core&#xff09;。因此使用微信重新推送&#xff0c;希望能帮到大家。自从我用了EF&#xff0c;每次都很关心是否有潜在的性能问题。所以每次…

微软内部全面拥抱开源流程Inner Source

微软过去几年一直是 GitHub 平台上开源贡献者最多的公司。不仅如此&#xff0c;微软还将继续拥抱开源&#xff0c;内部有一项名为 Inner Source 的计划&#xff0c;将开源开发流程引入到公司内部。事实上&#xff0c;Inner Source 已经存在于微软内部多年&#xff0c;包括更多代…

k8s使用helm打包chart并上传到腾讯云TencentHub

本文只涉及Helm的Chart操作&#xff0c;不会对其他知识进行过多描述。至于安装这块&#xff0c;麻烦自行百度吧&#xff0c;一大堆呢。在容器化的时代&#xff0c;我们很多应用都可以部署在docker&#xff0c;很方便&#xff0c;而再进一步&#xff0c;我们还有工具可以对docke…

数据结构之基环树——骑士,Island,旅行加强版,Number of Simple Paths,Traffic Network in Numazu,Card Game

文章目录[ZJOI2008]骑士[IOI2008] Island[NOIP2018 提高组] 旅行 加强版CF1454E Number of Simple PathsTraffic Network in NumazuCard Game基环树的常见解法若干个基环树互相独立断环为链&#xff08;随便断一条&#xff09;环外树和环外树之间的树形DP环变链后整体可以用数据…

如何在ASP.NET Core中自定义Azure Storage File Provider

主题&#xff1a;如何在ASP.NET Core中自定义Azure Storage File Provider作者&#xff1a; Lamond Lu地址: https://www.cnblogs.com/lwqlun/p/10406566.html项目源代码&#xff1a; https://github.com/lamondlu/AzureFileProvider背景ASP.NET Core是一个扩展性非常高的框架…

美好生活从撸好代码开始

楔子 昨天晚上做了个梦&#xff0c;梦到老板对我说了一番道理&#xff0c;他说对家庭要用爱心&#xff0c;做人对社会要有包容心&#xff0c;对工作要有责任心&#xff0c;对老板要有同理心。 我深以为然。现在的老板确实太不容易了&#xff0c;尤其是作为一家承载梦想&#xf…

Dotnet全平台下APM-Trace探索

随着支撑的内部业务系统越来越多&#xff0c;向着服务化架构进化&#xff0c;在整个迭代过程中&#xff0c;会逐渐暴露出以下问题。传统依赖于应用服务器日志等手段的排除故障原因的复杂度越来越高&#xff0c;传统的监控服务已经无法满足需求。终端--> Nginx --> IIS --…

部署Chart应用并使用.net core读取Kubernetes中的configMap

上一篇文章讲了 k8s使用helm打包chart并上传到腾讯云TencentHub&#xff0c;今天就讲一下使用Helm部署应用并使用configMap代替asp.net core 中的appsettings.json文件。把Chart上传到TencentHub之后&#xff0c;我们就可以通过腾讯云的容器服务&#xff0c;直接部署Helm应用了…

EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

前言α角 与 β角关于α角 与 β角的介绍&#xff0c;请见上文 如何用EFCore Lazy Loading实现Entity Split。本篇会继续有关于β角的彩蛋在等着大家去发掘。/斜眼笑其他本篇的程序&#xff0c;可以在 https://github.com/kentliu2007/EFCoreDemo/tree/master/InheritanceWithE…

程序员过关斩将--快速迁移10亿级数据

菜菜呀&#xff0c;咱们业务BJKJ有个表数据需要做迁移程序员主力 Y总现在有多少数据&#xff1f;菜菜大约21亿吧&#xff0c;2017年以前的数据没有业务意义了&#xff0c;给你半天时间把这个事搞定&#xff0c;绩效给你A程序员主力 Y总有绩效奖金吗&#xff1f;菜菜钱的事你去问…

CodeForces - 76E Points

CodeForces - 76E Points 题意&#xff1a; 给你n个点的坐标&#xff0c;求所有一对点之间的距离的平方和 n<100000 题解&#xff1a; 直接暴力n2肯定不行&#xff0c;我们把这个的式子列出来&#xff1a; 代码&#xff1a; #include<bits/stdc.h> #define deb…

模板:Miller-RabinPollard-Rho(数论)

所谓 pollard-rho&#xff0c;就是泼辣的肉 &#xff08;逃&#xff09; 前言 许多题解都把这两个算法放在了一起。 那我也这样办吧&#xff01; miller-rabin可以在优秀的时间复杂度内完成对一个数的素性检测。 而pollard-rho则是立足于Miler-rabin之上&#xff0c;可以在 …

Asp.NetCore轻松学-部署到 Linux 进行托管

前言上一篇文章介绍了如何将开发好的 Asp.Net Core 应用程序部署到 IIS&#xff0c;且学习了进程内托管和进程外托管的区别&#xff1b;接下来就要说说应用 Asp.Net Core 的特性&#xff08;跨平台&#xff09;&#xff0c;将 .NetCore 部署到 Linux 中&#xff0c;主流的 Linu…

DevC++ 用C语言的多线程 实现简单的客户端和服务器

知识来源一&#xff1a; 使用Dev-C实现简单的客户端和服务器-CSDN博客 此先生的博客使用的是win32 SDK来创建多线程&#xff0c;然后鄙人对这个版本的多线程细节不明。于是又重新用C语言的线程替代win32API,以此继续学习服务器代码。 知识来源二&#xff1a;DevC 多线程创建…

从初创公司的角度来看微服务

在开展微服务的过程中&#xff0c;了解要考虑哪些因素可能是非常有挑战性的事情。没有可以直接使用的金科玉律。每个过程都是不同的&#xff0c;因为每个组织面临的都是不同的环境。在本文中&#xff0c;我将从初创公司的角度分享我们学习到的经验和面临的挑战&#xff0c;以及…

MySQL 集群方案介绍

mysql集群方案这里介绍2种&#xff0c;PXC 和 Replication。大型互联网程序用户群体庞大&#xff0c;所以架构设计单节点数据库已经无法满足需求。大家也深有体会&#xff0c;有一万人在学校网站查成绩或是选课的时候网站时常是访问不了或者相应特别特别慢。这种情况就凸显出来…

ML.NET案例详解:在.NET下使用机器学习API实现化学分子式数据格式的判定

半年前写过一篇类似的文章&#xff0c;题目是&#xff1a;《在.NET中使用机器学习API&#xff08;ML.NET&#xff09;实现化学分子式数据格式的判定》&#xff0c;在该文中&#xff0c;我介绍了化学分子式数据格式的基本知识&#xff0c;同时给出了一个案例&#xff0c;展示了如…

数据结构之线段树合并——永无乡,Lomsat gelral,Tree Rotations,Tree Rotations Escape Through Leaf

文章目录[HNOI2012]永无乡Lomsat gelral「POI2011 R2 Day2」旋转树木 Tree RotationsEscape Through Leaf线段树合并与 fhq-treap合并很类似&#xff0c;也是将两个不同根的线段树暴力合并至于时间复杂度&#xff0c;线段树合并一次是可以达到O(n)O(n)O(n)的&#xff0c;但是大…

吉特仓储管理系统--开源2018年源码

应该说今天过完&#xff0c;这个年就算真正意义上的过完了&#xff0c;没有想到的是又是在出差的路上写这样的文章。废话也不多说&#xff0c;写这篇文章主要的目的是想将去年吉特仓储管理系统开发的一个版本源代码开放出来&#xff0c;供各位开发者阅读使用。github 源代码地址…