为了介绍使用 ASP.NET Core 构建 GraphQL 服务器, 本文需要介绍一下 GraphQL, 其实看官网的文档就行.
什么是 GraphQL?
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述, 使得客户端能够准确地获得它需要的数据, 而且没有任何冗余, 也让 API 更容易地随着时间推移而演进, 还能用于构建强大的开发者工具.
官网地址: https://graphql.org/
中文网址(感觉不是官方的, 连 HTTPS 都不是): http://graphql.cn/
GraphQL 来自 Facebook, 它于 2012 年开始开发, 2015 年开源.
GraphQL 与编程语言无关, 可以使用很多种语言 / 框架来构建 Graph 服务器, 包括. NET Core.
像 GitHub,Pinterest,Coursera 等公司都在使用 GraphQL.
GitHub 的 API 到目前有 4 个版本, 第三个版本都是用的是 REST, 而第四个版本使用的是 GraphQL.
GraphQL 到底是什么?
这就是一个 GraphQL 查询的例子. 左边是查询, 右边是结果.
从这个例子可以看出, 查询是可以嵌套的, 所以使用 GraphQL 的客户端可以通过一次请求获得所有需要的数据.
每当对 GraphQL 服务器进行查询的时候, 这些查询首先都会依据一个类型系统对其进行验证. 每个 GraphQL 服务都会在 GraphQL schema 里定义类型信息.
可以把这个类型系统看作是你的 API 数据的蓝本, 它由你定义的一系列对象所支撑.
例如这个 User 对象:
GraphQL 经常被称作是一个: 声明式数据获取语言.
GraphQL 的设计原则
分层结构: GraphQL 的查询是有层次结构的, 字段可以内嵌其它字段; 查询和返回数据的结构是一致的.
以产品中心: GraphQL 是由客户端所需要的数据所驱动, 语言和运行时也支持客户端.
强类型: GraphQL 服务器由 GraphQL 类型系统所支撑. 在 schema 里, 每个数据点都有一个特定的类型, 针对这个类型还有验证.
客户端定制查询: GraphQL 服务器提供了可以让客户端进行定制查询的能力.
内省(introspective): 客户端可以查询 GraphQL 服务器的类型系(schema).
为什么使用 GraphQL?
谈起 GraphQL, 总是离不开 REST.
如果您想了解 REST in ASP.NET Core, 请看我写的这个系列文章: https://www.cnblogs.com/cgzl/p/9178672.html#REST
REST 有几个问题:
过度获取: REST 里 GET 请求的查询结果通常比较大, 并且超过了客户端的需求:
这里我只需要 name,height, 和 mass, 但是却返回了所有的字段.
而使用 GraphQL, 我只需要查询我需要的数据:
获取不足: 使用 REST 时, 我想获取部门和部门的人员, 通常我需要先请求查询部门列表; 然后遍历返回的部门列表, 再次发出请求查询每个部门下的人员, 所以是 N+1 查询.
而使用 GraphQL, 我就可以通过一个查询请求 (嵌套的) 取得相应的结果.
不灵活: 随着 API 的演进, REST 需要随时创建新的端点, 所以 REST API 的端点增长速度很快; 此外有版本和兼容性需要谨慎考虑.
而 GraphQL, 典型的结构是只有一个端点. 这个单端点就像 API 网关一样组织了多个数据源, 这样就会更简单.
综上, 使用 GraphQL 的好处是:
避免多重 REST 请求
向下兼容, 无需考虑版本
可以对现有的数据源 (例如 REST API) 进行包装
与开发语言无关
GraphQL 查询
我通过 GitHub 的 GraphQL Explorer 来进行演示, 网址是: https://developer.GitHub.com/v4/explorer/
登录之后, 其效果如下:
GitHub 使用了 graphiql,graphiql 是一个浏览器内的 IDE, 它可以用来浏览和查询 GraphQL.
graphiql 的网址是: https://GitHub.com/graphql/graphiql .
下一篇文章, 我也会在. NET 项目里安装这个 graphiql.
graphiql 只是用来浏览查询 GraphQL 的一个浏览工具而已, 其它比较流行的工具还包括 GraphQL Playground 和 GraphQL Voyager 等.
第一个查询
打开 GitHub 的 GraphiQL 以后, 自动加载了一个查询语句, 我们点击运行按钮, 右侧就会返回查询的结果:
在这里, 我查询了浏览者 viewer 这个字段, 当前浏览该网页的就是我自己; 在查询里我还包括了 viewer 下的 login 字段, 也就是登录名.
结果以 JSON 形式返回, 其数据包含在 data 属性下, 结构和查询结构一致.
如果我还想在查询中包含浏览者的姓名, 那就加一个字段即可:
GraphQL 的查询也可以有注释:
GraphiQL 的智能提示
GraphiQL 是具有智能提示的功能的. 当你输入一个字母之后, 就是这种效果:
如果你什么都不输入, 还想知道有哪些字段, 那么就按 Alt + 空格:
但是在 Windows 上多少还是有些问题的, 因为 Alt + 空格也会弹出浏览器的菜单....
其实前面那个 query 关键字在这里是可以省略的, 点击 prettify 之后, 就会把 query 关键字去掉; 并且如果您的查询格式比较乱的话, 点击 prettify 也会对查询进行格式化:
查询参数
在 GraphQL 里, 每个字段都可以有自己的参数.
直接看例子. 下面这个例子里, 我想查询登录名为 Facebook 的仓库所有者:
括号里就是查询参数, 这个参数的作用就是过滤数据, 返回 login 字段等于 Facebook 的仓库所有者.
再看一个例子, 这次我要查询 repository, 参数是 name, 参数值是 graphql, 点击查询:
注意, 查询语句里有红色波浪线. 不出意外, 返回的了错误.
(所有的错误请求的返回结果都是这个格式的).
错误信息里告诉我们要查询 repository 这个字段, 必须要提供 owner 这个参数, 那么我们就加上这个参数:
这次终于返回了正确的结果.
也可以再添加几个字段:
GraphQL Schema
上面我介绍了几个查询的例子, 下面我介绍一下这个查询的后台工作原理.
上面这些字段的设定是由 GraphQL 的 schema 来决定的.
Schema 提供了你的数据中所有使用的对象类型.
它制定了所有值的类型.
打开 GitHub 的 Graphiql, 右侧有个 Docs 按钮, 也就是文档:
每当我们定义了一个 schema 之后, 文档就会自动生成.
打开 Docs, 可以看到两种操作类型:
Query, 查询, 也就是用来获取数据的.
Mutation, 变化, 也就是用来更新数据的.
点击 Query, 进去后我们可以在这里看见之前进行的那些查询:
那么就点击一下刚才的 repository 这个查询:
可以看到这个查询需要两个参数: owner 和 name, 类型都是字符串.
再返回到 Query, 仔细看一下那些和字段在一起的黄色字体的东西:
这些就是类型.
在类型里, 有的是常见的类型: 例如 String,Int,Float,Boolean,ID.
输入类型和返回类型
当定义 schema 的时候, 我们也会相应的定义所允许的输入类型, 它们可以是参数类型或字段类型.
输入类型可以是: Int,Float,String,Boolean,Null,Enum,List,Object.
例如:
后边的叹号, 表示该参数是必须的.
冒号后边的部分就是返回类型
当我们定义好 Schema 之后, 文档就生成了, 所以 GraphQL 是自我生成文档的.
查询 Schema
除了看文档之外, 你可以直接查询 schema, 这点在我们不使用 graphiql 的时候尤其有用.
这个查询里, 我们要查的是__schema 字段; 然后是它下面的 queryType 字段, queryType 将会返回 schema 下所有的查询; 然后我再查询 queryType 下的 name 和 description, 点击运行, 就会看到右边的结果: name 是 Query, 描述是它是 GitHub GraphQL 接口的 query root.
这个结果和文档里的描述是一样的:
下面再加上 fields 字段看看:
这个结果的 fields 字段就包括很多内容了: codeOfConduct,license 等等. 而这些就是 root query 所有支持的字段.
查询 Type
除了查询 schema 外, 另一个有用的查询就是 Type 的查询.
例子, 查询 Repository 这个类型的相关信息, 查询__type 字段, 带着参数 name 为 Repository:
这个查询结果也和文档里的一致, 我就不贴图了.
这篇先到这, 明天继续.
来源: https://www.cnblogs.com/cgzl/p/9734083.html