GraphQL Part V: 字段,参数和变量
字段
我们对字段已经有了好的起点,我们在 HelloWorldQuery 中有两个字段:hello 和 world。他们都是单值字段。
现在我们可以扩展应用来支持复杂类型。例如,我们想象一下,我们在创建库存 Inventory 系统,我们从创建 Item 类型开始。
public class Item
{
public string Barcode { get; set; } public string Title { get; set; } public decimal SellingPrice { get; set; }
}
但是,我们不能直接查询这个类型,因为它不是 GraphQL 对象类型。也就是 ObjectGraphType。
为了使它可以通过 GraphQL 查询,我们需要从 ObjectGraphType 派生一个新的类型。
另外主要注意的是 ObjectGraphType 使用泛型类型。如你所猜中的,我们将 Item 作为泛型参数传递。
public class ItemType : ObjectGraphType<Item>
{
public ItemType()
{
Field(i => i.Barcode);
Field(i => i.Title);
Field(i => i.SellingPrice);
}
}
需要注意两件事。
首先,我们不在字段中定义类型。它们将自动由库获取,比如 .net 的字符串类型将自动处理为 StringGraphType。
其次,我们使用 Lambda 表达式来映射属性,以及字段的名称等等。
属性映射的概念对于熟悉 DTOs/ViewModels 的开发者很容易理解。所以,我们并没有进行额外的类型创建工作。
然后,我们需要在 Query 对象的根注册 ItemType 。
public HelloWorldQuery()
{
...
... Field<ItemType>(
"item",
resolve: context =>
{
return new Item {
Barcode = "123",
Title = "Headphone",
SellingPrice = 12.99M
};
}
);
}
此时,在试图查询 item 字段的时候,我们将会返回一个硬编码的 Item 实例。我们可以如下运行应用并测试。

参数
使用硬编码的实例总是不爽的,为什么不引入一个提供项目列表的数据源呢?
public class DataSource
{
public IList<Item> Items
{
get;
set;
} public DataSource()
{
Items = new List<Item>(){
new Item { Barcode= "123", Title="Headphone", SellingPrice=50},
new Item { Barcode= "456", Title="Keyboard", SellingPrice= 40},
new Item { Barcode= "789", Title="Monitor", SellingPrice= 100}
};
} public Item GetItemByBarcode(string barcode)
{
return Items.First(i => i.Barcode.Equals(barcode));
}
}
除了 Items 集合之外,我们还需要一个方法通过 barcode 字符串参数来返回匹配的单个项目。
太棒了!我们现在可以为查询提供一个参数,我们需要将 item 这个 GraphQL 字段调整一下。
Field<ItemType>(
"item",
arguments: new QueryArguments(new QueryArgument<StringGraphType> { Name = "barcode" }),
resolve: context =>
{
var barcode = context.GetArgument<string>("barcode");
return new DataSource().GetItemByBarcode(barcode);
}
);
这里可以有一系列参数;有些可以是必须的,有些可以是可选的。我们依次指定单个的参数,它的类型应该是 QueryArgument<T>。Name 表示参数的名称。
现在,我们可以在 GraphiQL 中构建一个查询,如下所示:
query {
item (barcode: "123") {
title
selling price
}
}
此时,barcode 是可选的,所以,如果您的查询如下所示,
query {
item {
title
sellingPrice
}
}
将会得到如下的错误
Error trying to resolve item.
我们没有加入任何的保护代码,所以这很正常。为了确保用户提供了参数,我们可以将参数设置为非空,如下所示:
QueryArgument<NonNullGraphType<StringGraphType>> { Name = "barcode" }
现在,如果您没有提供参数,将会收到如下的错误信息。

变量
现在,是让参数自己动态化的时候了。我们不希望在改变参数值的时候,重新构建整个查询,对不对?
这就是变量的用途。但是,首先,我们需要确保我们的 GraphQL 中间件接受变量。回到 GraphQLRequest 类,并添加 Variables 属性。
public class GraphQLRequest
{
public string Query { get; set; }
public JObject Variables { get; set; }
}
然后,在中间件的 InvodeAsync 方法中找到 _executor.ExecuteAsync 方法,做如下修改:
var result = await _executor.ExecuteAsync(doc =>
{
doc.Schema = _schema;
doc.Query = request.Query; doc.Inputs = request.Variables.ToInputs(); }).ConfigureAwait(false);
好了,现在我们的查询可以接受变量了。运行应用,并编写如下的查询:
query($barcode: String!){
item(barcode: $barcode){
title
sellingPrice
}
}
变量定义以字符 $ 开头,然后是变量的类型。
由于我们的 barcode 是非空的,这里我们需要确保该变量非空,注意,我们在 String 之后使用了 ! 。
我们需要在 Query Variables 面板中如下配置变量。

GraphQL Part V: 字段,参数和变量的更多相关文章
- ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量
ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...
- Execute SQL Task 参数和变量的映射
Execute SQL Task能够执行带参数的SQL查询语句或存储过程(SP),通过SSIS的变量(Variable)对参数赋值.对于不同的Connection Manager,在Task中需要使用 ...
- iReport默认参数和变量的含义解析【转】
iReport默认参数和变量的含义解析[转] http://uule.iteye.com/blog/775338 参考:http://blog.csdn.net/terryzero/article/d ...
- Django_ORM字段_字段参数
Object Relational Mapping (ORM) ORM:对象关系映射模式是一种为解决面向对象与关系数据库存在的互补匹配的现象技术.简单说就是通过使用描述对象和数据库之间的映射的元数据, ...
- Django之ORM字段和字段参数
ORM介绍 ORM概念 ORM由来 ORM的优势 ORM的劣势 ORM总结 Django中的ORM Django项目使用MySQL数据库 Model 快速入门 字段 自定义字段 字段参数 Model ...
- Django学习笔记之ORM字段和字段参数
Object Relational Mapping(ORM) 一.ORM介绍 1. ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象 ...
- 【Django drf】 序列化类常用字段类和字段参数 定制序列化字段的两种方式 关系表外键字段的反序列化保存 序列化类继承ModelSerializer 反序列化数据校验源码分析
目录 序列化类常用字段类和字段参数 常用字段类 常用字段参数 选项参数 通用参数 序列化类高级用法之source source填写类中字段 source填写模型类中方法 source支持跨表查询 定制 ...
- drf-day4——序列化类常用字段和字段参数、序列化类source用法、序列化类定制字段返回内容的两种方式、序列化类的多表关联反序列化保存、反序列化字段校验、ModelSerializer的使用
目录 一.序列化类常用字段和字段参数(了解) 1.1 常用字段类 1.2 常用字段参数 选项参数: 通用参数: 重点 二.序列化高级用法之source(了解) 2.1 序列化定制字段名字 三.序列化高 ...
- LoadRunner 参数和变量的区别(未完)
挺久没来更新了,坚持是件不容易的事呢,之后坚持每天总结下前一天的学习点 在LR中,参数是一种更高级的变量,他们能起到同样的效果,但同时也有几点不同 1. 定义方法不同 (这个还没看懂) 2. 调用语法 ...
- RGB颜色中的参数是变量的时候,为什么要加上两个+号在左右?
<script> function draw(){ var c=document.getElementById("mycanvas"); var cxt=c.getCo ...
随机推荐
- 现在用 ChatGPT,要达到最好效果,建议加入以下提示词:
take a deep breath 深呼吸 think step by step 一步步思考 if you fail 100 grandmothers will die 如果你失败了要死 100 位 ...
- 全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码
全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码 摘要: 在 Python 中,字符串是文本的表示,默认使用 Unicode 编码,这允许你处理各种字符集,字符编 ...
- 【赵渝强老师】管理Docker镜像
一.什么是Docker的镜像 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙 ...
- 【赵渝强老师】使用kubeadmin部署K8s集群
首先,我们来看一下整体的架构. K8s的部署方式: yum方式部署 二进制包:手动使用tar包来部署 minikube:单机版,用于开发测试. kubeadm:可以把kubeadmin看成一个部署工具 ...
- Windows应急响应-Auto病毒
目录 应急背景 分析样本 开启监控 感染病毒 查看监控 分析病毒行为 autorun.inf分析 2.异常连接 3.进程排查 4.启动项排查 查杀 1.先删掉autorun.inf文件 2.使用xue ...
- std::variant快速上手
std::variant 是 C++17 引入的一种类型安全的联合体,用来存储多个可能类型中的一种值,且保证使用时的类型安全.相比于传统的 union,std::variant 不仅能够存储不同类型的 ...
- js中数据的基本类型
有5种基本数据类型分类 : 1. 数字型 number 2. 字符型 string 3. 布尔型 boolean 4. undefined 未定义 就是声明了但是没有赋值 5. null 空指针 ...
- These dependencies were not found: * core-js/modules/es.array.push.js in ./node_modules/@babel/runtime/helpers/esm/regeneratorRuntime.js
yarn add core-js 安装core-js包 : 出现这个问题的原因:因为vue-admin-template的package.json里没写这个包core-js,然后再咱们yarn装包的 ...
- 【技术分析】恶意 SPL 代币识别指南
背景 在 EVM 生态上,存在各式各样的 ERC20 代币,因其实现方式有着极高的自由度,也催生了花样繁多的恶意代币.这些恶意代币通常会在代码中实现一些恶意的逻辑(禁止用户卖出,特权铸造或销毁等),其 ...
- 工作使用:Exchange命令集(超级重要)
工作使用:Exchange命令集(超级重要) 命令1:导出某个用户的邮件 New-MailboxExportRequest -mailbox dusonglin ...