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 III: 依赖注入

参考资料

GraphQL Part II: 中间件的更多相关文章

  1. ASP.NET Core中使用GraphQL - 第二章 中间件

    前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, app ...

  2. ASP.NET Core中使用GraphQL - 最终章 Data Loader

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

  3. ASP.NET Core中使用GraphQL - 第三章 依赖注入

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

  4. ASP.NET Core中使用GraphQL - 第四章 GraphiQL

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

  5. ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量

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

  6. ASP.NET Core中使用GraphQL - 第六章 使用EF Core作为持久化仓储

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

  7. ASP.NET Core中使用GraphQL - 第七章 Mutation

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

  8. ASP.NET Core中使用GraphQL - 第八章 在GraphQL中处理一对多关系

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

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

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

  10. graphql 项目搭建(二)

    一.Express基本框架 1.新建一个文件夹gql-server vscode 打开项目,在终端下输入yarn init -y 生成package.json 包(如果没安装yarn ,npm也一样, ...

随机推荐

  1. OOOPS:零样本实现360度开放全景分割,已开源 | ECCV'24

    全景图像捕捉360°的视场(FoV),包含了对场景理解至关重要的全向空间信息.然而,获取足够的训练用密集标注全景图不仅成本高昂,而且在封闭词汇设置下训练模型时也受到应用限制.为了解决这个问题,论文定义 ...

  2. 【官宣】2024 DTC数据技术嘉年华全议程发布:汇聚行业精英,共襄年度盛宴

    龙腾四海内,风云际会时.由墨天轮数据社区和中国数据库联盟(ACDU)主办的第十三届数据技术嘉年华 将于2024年4月12日至13日在北京新云南皇冠假日酒店盛大召开.本次大会的主题是"智能·云 ...

  3. iOS解决嵌套在ScrollView中的TableView滑动手势冲突问题

    在项目开发中用到了这种需求,顶部两个选项卡,底部列表有侧滑手势,布局是就不说了,遇到的问题是左滑的时候添加滑动手势效果.一直纠结了很久,后来想到可能是手势冲突的问题. 解决办法开启多手势代理即可,我是 ...

  4. dotnet Core 静态方法和构造方法

    // 静态方法: // 特点:1.生命周期一旦创建-应用结束 才会结束 2.全局的 3.效率高(放在内存中) // 用户:用户登录,系统配置信息,系统设置,SQLHelper // 注意:静态的东西创 ...

  5. 25. http 常见状态码

    状态码的分类: 2xx:表明请求被成功接收并处理 : 3xx:表示要完成请求,需要进一步操作. 通常,这些状态代码用来重定向 :重定向就是 从 a 地址跳转到 b 地址 : 4xx:客户端错误,请求错 ...

  6. 结构体(C语言)

    目录 1. 结构体类型的声明 1.1 结构体回顾 1.1.1 结构的声明 1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明 1.3 结构的自引用 2. 结构体内存对齐 2.1 对齐规则 2 ...

  7. 字符串、列表、元组、字典(python)

    文章目录 1.python字符串 1.1 python访问字符串中的值 1.2Python 字符串连接 1.3Python字符串运算符 2.python列表 2.1访问列表中的值 2.2更新列表 2. ...

  8. 2个月搞定计算机二级C语言——真题(5)解析

    1. 前言 本篇我们讲解2个月搞定计算机二级C语言--真题 5 2. 程序填空题 2.1 题目要求 2.2 提供的代码 #include <stdio.h> double fun(int ...

  9. WinDbg调试命令之线程操作

    WinDbg的线程操作命令可以帮助开发人员诊断和解决多线程应用程序中的问题,常用的命令有以下这些. ~*e - 列出当前进程中的所有线程 这个命令会列出当前进程中的所有线程,包括它们的线程ID.状态. ...

  10. 强行修改 User-Agent, 访问对应的端

    location /{ proxy_pass http://localhost:18080; proxy_set_header User-Agent "Mozilla/5.0 (Window ...