前文: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);
});

这个中间件负责输出了当前查询的结果。

中间件的定义:

中间件是装载在应用程序管道中的组件,负责处理请求和响应,每一个中间件

  • 可以选择是否传递请求到应用程序管道中的下一个组件
  • 可以在应用程序管道中下一个组件运行前和运行后进行一些操作

来源: Microsoft Documentation

实际上中间件是一个委托,或者更精确的说是一个请求委托(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 - 第二章 中间件的更多相关文章

  1. ASP.NET Core中使用GraphQL - 第九章 在GraphQL中处理多对多关系

    ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...

  2. ASP.NET Core中使用GraphQL - 第一章 Hello World

    前言 你是否已经厌倦了REST风格的API? 让我们来聊一下GraphQL. GraphQL提供了一种声明式的方式从服务器拉取数据.你可以从GraphQL官网中了解到GraphQL的所有优点.在这一系 ...

  3. ASP.NET Core 中文文档 第二章 指南(4.6)Controller 方法与视图

    原文:Controller methods and views 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘) .张仁建(第二年.夏) .许登洋(Seay) .姚阿勇 ...

  4. ASP.NET Core 中文文档 第二章 指南(4.4)添加 Model

    原文:Adding a model 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:许登洋(Seay).孟帅洋(书缘).姚阿勇(Mr.Yao).夏申斌 在这一节里,你将添加一些类来 ...

  5. 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 ...

  6. 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 ...

  7. ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序

    原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...

  8. 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 ...

  9. ASP.NET Core 中文文档 第二章 指南(4.5)使用 SQL Server LocalDB

    原文:Working with SQL Server LocalDB 作者:Rick Anderson 翻译: 魏美娟(初见) 校对: 孟帅洋(书缘).张硕(Apple).许登洋(Seay) Appl ...

随机推荐

  1. Django—models相关操作

    一.在django后台admin管理页面添加自己增加的表结构 通过终端命令:python3 manage.py makemigrations, python3 manage.py migrate 我们 ...

  2. java集合之ArrayList,TreeSet和HashMap分析

    java集合是一个重点和难点,如果我们刻意记住所有的用法与区别则是不太现实的,之前一直在使用相关的集合类,但是没有仔细研究区别,现在来把平时使用比较频繁的一些集合做一下分析和总结,目的就是以后在需要使 ...

  3. bzoj 4565 状压区间dp

    我还以为我状压很好...... 噗!!! 果然我区间很差... f[i][j][s]表示i~j段,合并后的状态为s所得的最大收益 枚举i,j,k,s. f[i][j][s<<1]=max( ...

  4. 【移动端web】软键盘兼容问题

    软键盘收放事件 这周几天遇到了好几个关于web移动端兼容性的问题.并花了很长时间去研究如何处理这几种兼容问题. 这次我们来说说关于移动端软键盘的js处理吧. 一般情况下,前端是无法监控软键盘到底是弹出 ...

  5. 一步一步理解 python web 框架,才不会从入门到放弃 -- 简单登录页面

    上一节,我们基本了解了 Django 的一些配置,这一节,我们将通过一个简单的登录页面,进一步学习 Django 的使用. 新建项目 首先,新建一个 Django 项目,记得别弄错了哦. settin ...

  6. phper的Go之旅(-)--书写前言

    前言:由于我使用的主力机是mac,所以整系列教程都以mac为主,后期可能会更新windows,有时间的话,截止写这篇博客的时间我是一个全职php开发工程师,之所以要写这篇 教程原因就是现在技术语言层出 ...

  7. com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server 报错问题

    com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known serve ...

  8. Kubernetes的DaemonSet(下篇)

    用Daemon Pod来进行通信 使用Pod来再DaemonSet中通信的手段有: 推的方式:在DaemonSet中的Pod会被配置成发送更新到如状态数据库这样的服务.这些都没有客户端. IP+端口方 ...

  9. 用系统为centos6的主机,搭建PXE服务器,实现批量安装centos6,7系统

    1. iptables -F setenforce 0 临时关掉selinux,清掉防火墙 永久生效更改配置文件:vim /etc/sysconfig/selinux chkconfig iptabl ...

  10. ArcGIS API For Javascript_4.8-渲染器SimpleRenderer

    SimpleRenderer require(["esri/renderers/SimpleRenderer"], function(SimpleRenderer) { /* co ...