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

    参考资料

  • 相关阅读:
    C#:String.Format数字格式化输出
    System.BadImageFormatException : 未能加载文件或程序集“Medici.PaymentRecover, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。试图加载格式不正确的程序。
    How to debug windows service
    中文字符utf-8编码原则
    获取当前文件的绝对路径
    finfo_file
    usort 函数
    snmp 简单网管协议
    $this
    prinft he sprintf
  • 原文地址:https://www.cnblogs.com/haogj/p/9155952.html
Copyright © 2020-2023  润新知