GraphQL简介
什么是GraphQL
GraphQL是API技术的新前沿。
它是一种API查询语言,以及一组用于执行查询的服务器端运行时(服务端可以以各种后端语言实现)。
它与特定技术无关,你可以用任何语言实现它。

它是一种直接与REST(REpresentational State Transfer)API 竞争的新方案,就像REST 之前与SOAP竞争一样。
GraphQL是在Facebook上开发的,就像最近震撼JavaScript世界的许多技术一样,如React和React Native,它在2015年公开发布 - 尽管Facebook在内部使用它几年。
除了Facebook,许多大公司都在采用GraphQL,包括GitHub,Pinterest,Twitter,Sky,纽约时报,Shopify,Yelp等数千家公司。
GraphQL的原则
GraphQL只公开单个端点。
你使用特殊的查询语法向该端点发送查询。该查询只是一个字符串。
服务器使用JSON对象来响应查询。
下面让我们看一下这种查询的第一个例子。此查询获取id=1
的人员姓名:
GET /graphql?query={ person(id: "1") { name } }
或者:
{
person(id: "1") {
name
}
}
我们将收到如下的JSON响应:
{
"name": "Tony"
}
让我们增加一点复杂性:获取某个人的姓名和所在城市,其中城市从address
对象中提取。我们不关心地址的其他细节,因为我们没有请求它们,服务器也不返回,
GET /graphql?query={ person(id: "1") { name, address { city } } }
或者
{
person(id: "1") {
name
address {
city
}
}
}
{
"name": "Tony",
"address": {
"city": "York"
}
}
综上所述,我们获得的数据与我们发送的请求的结构基本相同,并且填充了所获取的值。
GraphQL vs REST
由于REST是构建API的一种流行方法,并且比GraphQL更广泛,我们假设你已经熟悉了,让我们看看GraphQL和REST之间的差异。
Rest是一个概念
REST是一个事实上的架构标准,但它实际上并没有规范和大量的非官方定义。GraphQL有一个规范草案,它是一种查询语言而不是一种体系结构,围绕着它构建了一套定义良好的工具(以及一个繁荣的生态系统)。
虽然REST建立在现有架构之上,而在最常见的场景中是HTTP,但另一方面,GraphQL正在构建自己的约定。这可能是一个优势点,因为REST通过在HTTP层上缓存而免费获益。
单个端点
GraphQL只有一个端点,你可以在其中发送所有查询。如果使用REST方法,你可以创建多个端点,并使用HTTP 动词来区分读操作(GET
)和写操作(POST
,PUT
,DELETE
)。GraphQL不使用HTTP动词来确定请求类型。
根据你的需求量身定制
使用REST,你通常无法选择服务器返回给你的内容,除非服务器使用稀疏字段集实现部分响应,并且客户端使用该功能。API维护者无法强制执行此类过滤。
API通常会向你返回比你需要的信息更多的信息,除非你也控制API服务器,并为每个不同的请求定制响应。
使用GraphQL,您可以明确地请求您需要的信息,您不能从完整的响应默认值中“选择退出”,只会强制选择您想要的字段。
这有助于节省服务器上的资源,因为你可能需要较少的处理流程以及很少的带宽,因为要传输的有效负载较小。
GraphQL可以轻松监控字段的使用情况
使用REST,除非强制使用稀疏字段集,否则无法确定客户端是否使用了字段,因此在进行重构或弃用时,无法确定实际使用情况。
GraphQL可以跟踪客户端使用的字段。
访问嵌套数据资源
GraphQL允许生成少得多的网络调用。
我们举个例子:你需要访问一个人的朋友的名字。如果你的REST API公开了一个/person
端点,该端点返回一个带有朋友列表的人物对象,你通常首先通过执行获取人员信息GET /person/1
,其中包含其朋友的ID列表。
除非这个人的朋友列表已经包含朋友姓名,否则有100个朋友需要向/person
端点发出101个HTTP请求,这是一个巨大的时间成本,也是一个资源密集型操作。
使用GraphQL,你只需要一个请求,该请求会询问这个人的朋友的姓名。
类型
REST API基于JSON,无法提供类型控制。GraphQL有一个Type System。
哪一个更好?
世界各地的组织正在质疑他们的API技术选择,他们正试图找出从REST迁移到GraphQL是否最适合他们的需求。
当你需要公开复杂的数据表示,以及客户端可能只需要数据的子集,或者他们定期执行嵌套查询以获取所需数据时,GraphQL非常适合。
与编程语言一样,没有单一的赢家,这完全取决于你的需求。
GraphQL查询
在本文中,你将了解GraphQL查询是如何组成的。
我将介绍的概念是
- 字段和参数
- 别名
- 片段
字段和参数
下面是一个简单的GraphQL查询:
{
person(id: "1") {
name
}
}
在此查询中,你会看到2个字段和1个参数。
该字段person
返回一个Object,其中包含另一个字段类型是String。
参数允许我们指定要引用的人。我们传递了一个id
,如果我们交互的接口提供了通过名字来查找人的功能,我们也可以传递一个名字参数。
参数不限于任何特定字段,我们可以通过limit
参数,指定希望API返回的朋友数量:
{
person(id: "1") {
name
friends(limit: 100)
}
}
别名
你可以要求API返回具有别名的字段,例如:
{
owner: person(id: "1") {
fullname: name
}
}
将返回
{
"data": {
"owner": {
"fullname": "Tony"
}
}
}
此功能除了为客户端代码创建更多临时命名外,如果你需要在同一查询中引用同一端点2次,这是唯一可以使用的方法:
{
owner: person(id: "1") {
fullname: name
}
first_employee: person(id: "2") {
fullname: name
}
}
片段
在上面的查询中,我们重复使用了person
结构。片段允许我们指定结构(对许多字段非常有用):
{
owner: person(id: "1") {
...personFields
}
first_employee: person(id: "2") {
...personFields
}
}
fragment personFields on person {
fullname: name
}
GraphQL变量
更复杂的GraphQL查询需要使用变量,使用变量可以动态指定查询中使用的值。
在这种情况下,我们在查询中添加了person id作为字符串:
{
owner: person(id: "1") {
fullname: name
}
}
id很可能在我们的程序中动态改变,所以我们需要一种方法来传递它,而不是字符串插值。
使用变量,可以将相同的查询写为
query GetOwner($id: String) {
owner: person(id: $id) {
fullname: name
}
}
{
"id": "1"
}
在此代码段中,我们已将GetOwner
名称分配给查询。可以把它想象成命名函数,而前面的查询类似一个匿名函数。当你的应用程序中有大量查询时,命名查询很有用。
带有变量的查询定义看起来像一个函数定义,工作方式也很相似
必选变量
附加!
到类型:
query GetOwner($id: String!)
只需要在类型后面附加!
就能指定该字段为必填字段
指定变量的默认值
你可以使用以下语法指定默认值:
query GetOwner($id: String = "1")
GraphQL指令
指令可以根据变量为true或false来包含或排除字段。
query GetPerson($id: String) {
person(id: $id) {
fullname: name,
address: @include(if: $getAddress) {
city
street
country
}
}
}
{
"id": "1",
"getAddress": false
}
在这种情况下,如果getAddress
我们传递的变量为true,我们也会得到地址字段,否则不会。
我们有两个指令可用:include
(如果为真则包括),skip
与include
相反(如果为true,则排除)
@include(if:Boolean)
query GetPerson($id: String) {
person(id: $id) {
fullname: name,
address: @include(if: $getAddress) {
city
street
country
}
}
}
{
"id": "1",
"getAddress": false
}
@skip(if:Boolean)
query GetPerson($id: String) {
person(id: $id) {
fullname: name,
address: @skip(if: $excludeAddress) {
city
street
country
}
}
}
{
"id": "1",
"excludeAddress": false
}
GraphQL简介的更多相关文章
- 使用ASP.NET Core支持GraphQL -- 较为原始的方法
GraphQL简介 下面是GraphQL的定义: GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述 ...
- GraphQL快速入门教程
摘要: 体验神奇的GraphQL! 原文:GraphQL 入门详解 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. GraphQL简介 定义 一种用于API调用的数据查询语言 ...
- 使用ASP.NET Core支持GraphQL( restful 配套)
https://github.com/graphql-dotnet https://github.com/graphql GraphQL简介 官网:https://graphql.cn/code/ 下 ...
- 试一试 GraphQL
GraphQL 简介 一种用于 API 的查询语言. GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整 ...
- .NET Core 3.0即将发布!
期待已久的.NET Core 3.0即将发布! .NET Core 3.0在.NET Conf上发布.大约还有9个多小时后,.NET Conf开始启动. 为期3天的大概日程安排如下: 第1天-9月23 ...
- 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下)
上一篇文章:https://www.cnblogs.com/cgzl/p/9734083.html 处理数据 嵌套字段 看例子: 我想查看viewer下的repositories.注意里面的edges ...
- 《React Native 精解与实战》书籍连载「Node.js 简介与 React Native 开发环境配置」
此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...
- 完爆Facebook/GraphQL,APIJSON全方位对比解析(三)-表关联查询
相关阅读: 完爆Facebook/GraphQL,APIJSON全方位对比解析(一)-基础功能 完爆Facebook/GraphQL,APIJSON全方位对比解析(二)-权限控制 自APIJSON发布 ...
- ASP.NET Core 1.1 简介
ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...
随机推荐
- django-带参数路由
路由urls.py from django.conf.urls import url from goods.views import IndexView, DetailView, ListView u ...
- mssql 清理死锁
-存储过程 我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句.SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用 ...
- HDU 2887 Watering Hole(MST + 倍增LCA)
传送门 总算是做上一道LCA的应用题了... 题意:有$n$个牧场, $m$根管道分别连接编号为$u,v$的牧场花费$p_{i}$,在第$i$个牧场挖口井需要花费$w_{i}$,有$P$根管道直接连通 ...
- WinDbg常用命令系列---清屏
.cls (Clear Screen) .cls命令清除调试器命令窗口显示. .cls 环境: 模式 用户模式下,内核模式 目标 实时. 崩溃转储 平台 全部 清屏前 清屏后
- WinDbg常用命令系列---输入内存值的命令e*
e, ea, eb, ed, eD, ef, ep, eq, eu, ew, eza (Enter Values) e*命令将您指定的值输入内存.不要将此命令与~e(Thread-Specific C ...
- linux命令之------Linux文档编辑
1.Vi和vim三种模式 (1)命令模式:移动光标 (2)插入模式:编辑文档 (3)末行模式:保存退出 不同模式操作示意图: 其中wq是保存退出,wq!强制保存退出:q不保存退出:q!强制不保存退出. ...
- P4936 题解
\(\text{Update}\)(2019.10.05): 递推公式推法更详细: 通项公式更新详细版: 单位矩阵的推法更加详细. 特别鸣谢 @Smallbasic 苣佬,是他教会了我推递推公式和通项 ...
- oracle/mysql java jdbc类型映射
MySQL数据类型 JAVA数据类型 JDBC TYPE 普通变量类型 主键类型 BIGINT Long BIGINT 支持 支持 TINYINT Byte TINYINT 支持 不支持 SMALLI ...
- spring boot jar包替换报错之Unable to open nested entry 'BOOT-INF/lib/cache-api-0.4.jar'.
spring boot用layout ZIP打出来的包能够支持外部classpath,但是当用rar/7zip替换其中的jar后,报下列错误: Unable to open nested entry ...
- eclipse没有server选项怎么解决
eclipse没有server选项怎么解决 步骤: 1,在eclipse菜单“Help”中选择“InstallNew Software”如下图所示. 2,然后在Work with中点击Add,如下图所 ...