graphql_GraphQL简介
graphql
有兴趣学习JavaScript吗? 在jshandbook.com上获取我的免费电子书
GraphQL是API( 应用程序编程接口 )中的新领域。
它是API的查询语言,是用于执行查询的一组服务器端运行时(以各种后端语言实现)。
它与特定技术无关,但是您可以使用任何语言来实现它。
它是一种直接与REST ( 代表性状态转移 )API 竞争的方法,就像REST首先与SOAP竞争一样。
GraphQL是在Facebook上开发的 ,就像最近震动世界的许多技术一样,例如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与REST
由于REST是构建API的一种流行方法,或者可以说是通用方法,因此可以假设您很熟悉REST,因此,让我们看看GraphQL和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端点,该端点返回带有好友列表的person对象,那么通常通常首先通过执行GET /person/1获取该人物信息,该列表包含其好友ID的列表。
除非一个人的朋友列表中已经包含该朋友的名字,否则您需要与100个朋友向/person端点进行101个HTTP请求,这将花费大量时间,并且也是一项资源密集型操作。
使用GraphQL,您只需要一个请求,即可请求一个人的朋友的名字。
种类
REST API基于无法提供类型控制的JSON。 GraphQL具有类型系统 。
哪一个更好?
世界各地的组织都在质疑他们的API技术选择,他们试图找出从REST迁移到GraphQL是否最适合他们的需求。
当您需要公开复杂的数据表示形式,或者客户端可能只需要数据的一个子集,或者客户端定期执行嵌套查询以获取所需的数据时,GraphQL是一个完美的选择。
与编程语言一样,没有一个赢家,这完全取决于您的需求。
GraphQL查询
在本文中,您将学习如何构成GraphQL查询。
我将介绍的概念是
- 字段和参数
- 别名
- 碎片
字段和参数
进行以下简单的GraphQL查询:
{
person(id: "1") {
name
}
}
在此查询中,您将看到2个字段和1个参数。
现场person返回其中包含另一个字段String的Object 。
该参数允许我们指定要引用的人。 我们传递一个id ,但我们也可以传递一个name参数,如果与我们交谈的API可以选择按名称查找一个人。
参数不限于任何特定字段,我们可以person列出一个friends字段,并可以使用limit参数来指定我们希望API返回多少个参数:
{
person(id: "1") {
name
friends(limit: 100)
}
}
别名
您可以要求API返回具有不同名称的字段,例如:
{
owner: person(id: "1") {
fullname: name
}
}
将返回
{
"data": {
"owner": {
"fullname": "Tony"
}
}
}
如果您需要在同一查询中两次引用相同的端点 ,则此功能除了为您的客户端代码创建更多临时命名之外,还可以使查询正常工作:
{
owner: person(id: "1") {
fullname: name
}
first_employee: person(id: "2") {
fullname: name
}
}
碎片
在上面的查询中,我们复制了人员结构。 片段使我们可以一次指定结构(在许多字段中非常有用):
{
owner: person(id: "1") {
...personFields
}
first_employee: person(id: "2") {
...personFields
}
}
fragment personFields on person {
fullname: name
}
GraphQL变量
更复杂的GraphQL查询需要使用变量 ,这是一种动态指定在查询内部使用的值的方法。
在这种情况下,我们将人员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!)
而不是$id: String将使$ id变量成为必需。
指定变量的默认值
您可以使用以下语法指定默认值:
query GetOwner($id: String = "1")
GraphQL指令
指令允许您在变量为true或false时包含或排除字段。
query GetPerson($id: String, $getAddress: Boolean) {
person(id: $id) {
fullname: name,
address: @include(if: $getAddress) {
city
street
country
}
}
}
{
"id": "1",
"getAddress": false
}
在这种情况下,如果我们传递的getAddress变量为true,那么我们还将获取地址字段,否则返回。
我们有2个指令可用: include ,我们刚刚看过(如果为true则包含),以及skip ,这是相反的(如果为true则跳过)
@include(如果:布尔值)
query GetPerson($id: String, $getAddress: Boolean) {
person(id: $id) {
fullname: name,
address: @include(if: $getAddress) {
city
street
country
}
}
}
{
"id": "1",
"getAddress": false
}
@skip(如果是布尔值)
query GetPerson($id: String, $excludeAddress: Boolean) {
person(id: $id) {
fullname: name,
address: @skip(if: $excludeAddress) {
city
street
country
}
}
}
{
"id": "1",
"excludeAddress": false
}
有兴趣学习JavaScript吗? 在jshandbook.com上获取我的免费电子书
翻译自: https://hackernoon.com/an-introduction-to-graphql-2c3f7d8fb4e0
graphql
更多推荐


所有评论(0)