ASP.NET Core中使用GraphQL - 第二章 中间件
前文:ASP.NET Core中使用GraphQL - 第一章 Hello World
中间件
如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件,
app.Run(async (context) =>
{
var result = await new DocumentExecuter()
.ExecuteAsync(doc =>
{
doc.Schema = schema;
doc.Query = @"
query {
hello
}
";
}).ConfigureAwait(false);
var json = new DocumentWriter(indent: true)
.Write(result)
await context.Response.WriteAsync(json);
});
这个中间件负责输出了当前查询的结果。
中间件的定义:
中间件是装载在应用程序管道中的组件,负责处理请求和响应,每一个中间件
- 可以选择是否传递请求到应用程序管道中的下一个组件
- 可以在应用程序管道中下一个组件运行前和运行后进行一些操作
实际上中间件是一个委托,或者更精确的说是一个请求委托(Request Delegate)。 正如他的名字一样,中间件会处理请求,并决定是否将他委托到应用程序管道中的下一个中间件中。在我们前面的例子中,我们使用IApplicationBuilder
类的Run()
方法配置了一个请求委托。
使用动态查询体替换硬编码查询体
在我们之前的例子中,中间件中的代码非常简单,它仅是返回了一个固定查询的结果。然而在现实场景中,查询应该是动态的,因此我们必须从请求中读取查询体。
在服务器端,每一个请求委托都可以接受一个HttpContext
参数。如果一个查询体是通过POST请求发送到服务器的,你可以很容易的使用如下代码获取到请求体中的内容。
string body;
using (var streamReader = new StreamReader(httpContext.Request.Body))
{
body = await streamReader.ReadToEndAsync();
}
在获取请求体内容之前,为了不引起任何问题,我们需要先检测一些当前请求
- 是否是一个
POST
请求 - 是否使用了特定的Url, 例如
/api/graphql
因此我们需要对代码进行调整。
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
。因此我们可以将请求体中的JSON字符串转换成一个包含Query
属性的复杂类型。
这个复杂类型代码如下:
public class GraphQLRequest
{
public string Query { get; set; }
}
下一步我们要做的就是,反序列化当前请求体的内容为一个GraphQLRequest
类型的实例。这里我们需要使用Json.Net
中的静态方法JsonConvert.DeserializeObjct
来替换之前的硬编码的查询体。
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来创建一个POST请求, 请求结果如下:
结果正确返回了。
本篇源代码: https://github.com/lamondlu/GraphQL_Blogs/tree/master/Part%20II
ASP.NET Core中使用GraphQL - 第二章 中间件的更多相关文章
- ASP.NET Core中使用GraphQL - 第九章 在GraphQL中处理多对多关系
ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...
- ASP.NET Core中使用GraphQL - 第一章 Hello World
前言 你是否已经厌倦了REST风格的API? 让我们来聊一下GraphQL. GraphQL提供了一种声明式的方式从服务器拉取数据.你可以从GraphQL官网中了解到GraphQL的所有优点.在这一系 ...
- ASP.NET Core 中文文档 第二章 指南(4.6)Controller 方法与视图
原文:Controller methods and views 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘) .张仁建(第二年.夏) .许登洋(Seay) .姚阿勇 ...
- ASP.NET Core 中文文档 第二章 指南(4.4)添加 Model
原文:Adding a model 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:许登洋(Seay).孟帅洋(书缘).姚阿勇(Mr.Yao).夏申斌 在这一节里,你将添加一些类来 ...
- ASP.NET Core 中文文档 第二章 指南(1)用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序
原文:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 作者:Daniel Roth.Steve Smith ...
- ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API
原文:Building Your First Web API with ASP.NET Core MVC and Visual Studio 作者:Mike Wasson 和 Rick Anderso ...
- ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序
原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...
- ASP.NET Core 中文文档 第二章 指南(4.1)ASP.NET Core MVC 与 Visual Studio 入门
原文:Getting started with ASP.NET Core MVC and Visual Studio 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:刘怡(Alex ...
- ASP.NET Core 中文文档 第二章 指南(4.5)使用 SQL Server LocalDB
原文:Working with SQL Server LocalDB 作者:Rick Anderson 翻译: 魏美娟(初见) 校对: 孟帅洋(书缘).张硕(Apple).许登洋(Seay) Appl ...
随机推荐
- python里如何保存float类型的小数的位数
python保留两位小数: In [1]: a = 5.026 In [2]: b = 5.000 In [3]: round(a,2) Out[3]: 5.03 In [4]: round(b,2) ...
- 底层网络技术以及IP编址
网络信息的传输在最底层总是依托于物理介质来进行传输的,这里的传输介质分为两种: 有线介质 导线管(导向媒体).例如:双绞线.同轴电缆.光纤等 无线介质 电磁波(非导向媒体):利用各种波长的电磁波充 ...
- return_fun.go 源码阅读
] } else { receive.To = "" } return receive }
- .Net core验证码生成
首先,项目添加对ZKWeb.System.Drawing的引用: 生成验证码代码如下: public class VierificationCodeServices { /// <summary ...
- DB2DB 一年多以来的重大更新
由于工作的原因,所以和 DB2DB 有较多的接触.但由于之前的版本一直能满足工作上的需要,所以直到最近才更新为最新版本,而总结了新版本的更新历史后,发现 DB2DB 一年多以来包括了以下重大的更新: ...
- 聚焦“云开发圆桌论坛”,大前端Serverless大佬们释放了这些讯号!
4月14日,由云加社区举办的TVP&腾讯云技术交流日云开发专场,暨"腾讯云-云开发圆桌论坛"在北京.深圳两地同步举行. 当天下午,一场主题为"基于大前端和node ...
- 干货,不小心执行了rm -f,除了跑路,如何恢复?
前言 每当我们在生产环境服务器上执行rm命令时,总是提心吊胆的,因为一不小心执行了误删,然后就要准备跑路了,毕竟人不是机器,更何况机器也有bug,呵呵. 那么如果真的删除了不该删除的文件,比如数据库. ...
- 前端性能优化 —— 添加Expires头与Cache-control区别
要:添加Expires头能有效的利用浏览器的缓存能力来改善页面的性能,能在后续的页面中有效避免很多不必要的Http请求,WEB服务器使用Expires头来告诉Web客户端它可以使用一个组件的当前副本, ...
- java对象与Json字符串之间的转化(fastjson)
1. 首先引入jar包 在pom.xml文件里加入下面依赖: <dependency> <groupId>com.alibaba</groupId> <art ...
- 开箱即用Bumblebee独立部署搭建webapi网关详解
在之前的章节里都是讲述如何在程序中使用Bumblebee来构建一个Webapi网关:但这样显然有些麻烦,毕竟很多时候可能只需要一个简单负载处理,还需要写个程序针对服务进行编写代码或配置的确是比较麻烦的 ...