GraphQL Part II: 中间件
GraphQL Part II: 中间件
如果您熟悉 ASP.NET Core 的中间件,您可能注意到在我们上一篇博客中我们已经拥有了一个中间件。在初始的空白应用中,中间件的职责是返回 hello World 响应。后来, 我们用我们的自定义代码替换了它, 以便它可以响应一些静态 GraphQL 查询的结果。
中间件是一种可以装配到应用处理管线中的软件,以便处理请求和响应。每个组件包括:
- 选择是否将请求传递给管线中的下一个组件
- 可以在管线调用下一个组件之前或者之后执行任务
事实上,中间件是一个代理,或者更精确地说,他是一个请求代理。如名字所提示,它处理传入的请求并决定是否传递到管线中的下一个中间件。在我们的案例中,我们使用 IApplicationBuilder 的 run() 扩展方法来配置请求代理。在 3 个扩展方法之间 ( use, run, map ),Run() 方法在请求管线中终止了进一步的请求处理。
我们中间件中的代码非常简单,仅仅返回硬编码的静态查询,但是,在真实场景下,query 应该是动态的,我们必须从传入的请求中获取它。
每个请求代理接受一个 HttpContet 对象。如果 query 是通过 HTTP 的 Post 方式提交,您可以使用如下代码读取请求体。
string body;
using (var streamReader = new StreamReader(httpContext.Request.Body))
{
body = await streamReader.ReadToEndAsync();
}
在读取其内容之前做校验工作,就不会带来危害。所以,让我们放置一个 if 来检查两件事:
- 它是 Post 请求吗?
- 它来自特定的 URL 地址吗?
我们的代码做如下修改:
if(context.Request.Path.StartsWithSegments("/api/graphql") &&
string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
{
string body;
using (var streamReader = new StreamReader(context.Request.Body))
{
body = await streamReader.ReadToEndAsync();
}
......
请求体重可以包含大量字段,但是,我们可以说传入的 GraphQL 查询在名为 query 的字段内。所以,我们可以解析 body 的内容到一个包含 Query 属性的复杂类型示例中。
复杂类型如下所示:
public class GraphQLRequest
{
public string Query { get; set; }
}
下一步要做的就是反序列化 body 内容到 GraphQLRequest 对象示例中,使用 Json.Net 的 JsonConvert.DeserializeObject 并替换前面硬编码的内容。
var request = JsonConvert.DeserializeObject<GraphQLRequest>(body); var result = await new DocumentExecuter().ExecuteAsync(doc =>
{
doc.Schema = schema;
doc.Query = request.Query;
}).ConfigureAwait(false);
在所有的修改之后,在 Startup.cs 中的 Run 方法如下所示:
app.Run(async (context) =>
{
if (context.Request.Path.StartsWithSegments("/api/graphql")
&& string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
{
string body;
using (var streamReader = new StreamReader(context.Request.Body))
{
body = await streamReader.ReadToEndAsync(); var request = JsonConvert.DeserializeObject<GraphQLRequest>(body);
var schema = new Schema { Query = new HelloWorldQuery() }; var result = await new DocumentExecuter().ExecuteAsync(doc =>
{
doc.Schema = schema;
doc.Query = request.Query;
}).ConfigureAwait(false); var json = new DocumentWriter(indent: true).Write(result);
await context.Response.WriteAsync(json);
}
}
});
现在,可以使用任何客户端 ( Postman 或者 Insomnia ) 发送一个包含 query 字段的 POST 请求.

我们几乎完成了工作,但是您可以看到大量的 new 代码创建对象,例如:new DocumentExecuter(),new Schema(), new DocumentWriter() 等等,下一节,我们将使用 ASP.NET Core 内置的依赖注入系统注入它们。
上一篇:GraphQL Part I: hello, world.
参考资料
GraphQL Part II: 中间件的更多相关文章
- ASP.NET Core中使用GraphQL - 第二章 中间件
前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, app ...
- ASP.NET Core中使用GraphQL - 最终章 Data Loader
ASP.NET Core中使用GraphQL - 目录 ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间 ...
- ASP.NET Core中使用GraphQL - 第三章 依赖注入
ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 SOL ...
- ASP.NET Core中使用GraphQL - 第四章 GraphiQL
ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...
- ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量
ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...
- ASP.NET Core中使用GraphQL - 第六章 使用EF Core作为持久化仓储
ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...
- ASP.NET Core中使用GraphQL - 第七章 Mutation
ASP.NET Core中使用GraphQL - 目录 ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间 ...
- ASP.NET Core中使用GraphQL - 第八章 在GraphQL中处理一对多关系
ASP.NET Core中使用GraphQL - 目录 ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间 ...
- ASP.NET Core中使用GraphQL - 第九章 在GraphQL中处理多对多关系
ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...
- graphql 项目搭建(二)
一.Express基本框架 1.新建一个文件夹gql-server vscode 打开项目,在终端下输入yarn init -y 生成package.json 包(如果没安装yarn ,npm也一样, ...
随机推荐
- java爬取航班实时数据
使用jsoup获取航班实时数据 优先使用携程航班数据 如果携程航班数据返回为空 则使用去哪儿航班信息 pom.xml <dependency> <groupId>org.js ...
- C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
错误原因 VS平台认为scanf函数不安全,要求换成scanf_s函数 解决方案 方案一:将scanf换成scanf_s[不建议] 将scanf换成scanf_s 但是,scanf_s函数只能在vs上 ...
- Android Qcom USB Driver学习(十三)
DPM Device Policy Manager deals with the USB Power Delivery resources used by one or more ports on t ...
- 精彩回顾|【ACDU 中国行·成都站】数据库主题交流活动成功举办!
2023年10月14日下午,[ACDU 中国行·成都站]在成都市武侯区星宸假日酒店圆满落下帷幕.本次活动由中国数据库联盟(ACDU)联合墨天轮社区主办,围绕「数据库技术及应用」这一主题,六位数据库资深 ...
- 第三方的开源库FluentVaidation校验字段的
内置的 using System.ComponentModel.DataAnnotations; 基本使用: 1. 安装包 FluentValidation.AspNetCOre 2. 注册服务 bu ...
- go~wasm插件的开发
Go和TinyGo是两种不同的Go语言编译器,它们之间有以下几点区别: 目标平台: Go:Go语言编译器主要面向通用计算机平台,如Windows.Linux.macOS等. TinyGo:TinyGo ...
- Android复习(一)基础知识
1. 现在可以使用 Kotlin.Java 和 C++ 语言编写 Android 应用 2.Android四大组件依然坚挺,这是基础并且没有改变的迹象 Activity 服务 广播接收器 内容提供程序 ...
- 为Linux安装NVIDIA显卡驱动
Linux如何安装NVIDIA驱动 我使用的是Debian系列的Kali Linux,X11,Gnome,4060 我想要安装的是NVIDIA自家的独显驱动程序 下文展示的是为Debian系列安装NV ...
- KubeSphere 3.1.1 发布,可以接入集群已有的 Prometheus
KubeSphere 作为一款面向应用的开源容器平台,经过 3 年的发展和 10 个版本的迭代,收获了两百多位开源贡献者,超过十万次下载,并有数千名社区用户用 KubeSphere 作为企业容器平台. ...
- 在 Debian 12 上安装 KubeSphere 实战入门
老 Z,运维架构师,云原生爱好者,目前专注于云原生运维,云原生领域技术栈涉及 Kubernetes.KubeSphere.DevOps.OpenStack.Ansible 等. 前言 知识点 定级:入 ...