原文连接:https://medium.com/@weblab_tech/graphql-everything-you-need-to-know-58756ff253d8前端
原文做者:Weblab Technologygit
译者:杨涛github
这篇文章的目的是指出GraphQL相关的主要功能和讨论特定API规范的优势和缺点。web
GraphQL一般被描述为一种"前端导向"的API技术,由于它让前端开发者以一种比之前简单得多的方式请求数据。Facebook引入了这种查询语言,它的目标是以符合直觉和可伸缩的方式定制客户端应用,以描述数据的先决条件和交互。最好的一点是这种查询语言不依赖于任何特定的数据库管理系统,而且获得了当前数据格式和编码方式的支持。spring
传统REST的一个基本问题是,客户端不能个性化的收集数据。除此以外,运行和控制多个端点(译者注:表示API的具体网址,也能够理解为 接口)是另外一个难点,由于客户端常常须要从多个端点获取数据。数据库
当创建起一个GraphQL服务器,只须要简单的URL就能获取和修改数据。所以,一个用户能够经过传递查询字符串和声明他们须要什么来向服务器请求数据集。后端
在咱们继续以前,在这你能够找到咱们的我的实践。 graphlql-example缓存
说到类似之处,REST和GraphQL都用于构建API。 另外,它们均可以经过HTTP进行管理。 至于差别,REST主要是一个以软件为中心的结构化概念,没有规范,也不求明确的工具集。它更关注API的稳定性而不是性能。 GraphQL,另外一方面,是一种被设计于经过HTTP管理端点,提升性能和适用性的查询语言。我甚至能够说,查询语言和开发web的架构风格放在一块儿作比较,可能看起来很奇怪:)。一些其余显著的不一样包括:性能优化
毫无疑问,数据获取是GraphQL的一个最引人瞩目的特色之一。经过标准的REST API去生成和获取数据,咱们可能须要向多个端点发起请求。相比之下,GraphQL提供了能够获取服务器数据的单端点bash
query {
books {
id
title
author
isbn
price
}
}
复制代码
因为在REST中每一个接口都包含固定的数据格式,相比GraphQL,它会让你拿到更多的多余数据。类似的,REST会发送额外的请求去获取相关数据。 对于上一个例子,GraphQL是很不同的。由于它是一种查询语言而且支持声明式获取数据,用户能够从服务器只获取他们须要的数据。
query {
books {
title
price
}
}
复制代码
在REST风格中,错误管理是很是简单的。咱们须要作的是检查HTTP的headers以及了解response的位置。经过状态码,咱们能快速的找到错误和合适的方式去解决它。另外一方面,在GraphQL中,咱们老是收到200 OK的状态码。
Request: query { books { error_field } }
Response:
Request Method:POST
Status Code: 200 OK
{“errors”:[{“message”:”Cannot query field \”error_field\” on type \”Book\”.”,”category”:”graphql”,”locations”:[{“line”:3,”column”:3}]}]}
复制代码
由于REST强制使用具备缓存机制的HTTP协议,你能够经过它避免获取多余资源。GraphQL,另外一方面,没有缓存机制,它把缓存的重任交给了用户。
数据控制会带来API的边界,任何的变更都会被视为一种破坏性的改变,而破坏性改变就须要更新API的版本。这也许就是大多数API选择版本控制的缘由。若是新API须要最新的版本,咱们就须要频繁在新API和原有API之间调整。[译者注:例如接口改变了某个字段的数据类型] 相比之下,GraphQL只返回咱们须要的数据,在不改变原有的请求的状况下,拿到最新的数据类型和字段。
当使用GraphQL,你能够方便的弃用一个字段。GraphQL用户确定会声明他们须要的字段。
‘author_name’ => [
‘type’ => Type::string(),
‘deprecationReason’ => ‘Deprecated. Use author field’,
],
复制代码
REST API 以不一样的方式运做。虽然基本的端点都能在REST API中获取,但不是全部端点都能返回稀疏字段。[译者注:便可能包含多余的字段] 相比之下,GraphQL很是容易监控特定字段的使用。API使用者能在特定的客户端部署获取到的字段。
REST的请求默认做为一个总体,GraphQL一般尽可能发送最少的请求。即使REST的每一个请求返回最基本的部分,相同状况下,GraphQL能传输更多的数据片断。
和默认采用能让客户端和代理端完美的工做的HTTP的REST不一样,GraphQL以彻底不一样的方法调用。固然,事情并无像REST同样简单,由于你须要调整你的数据集,使用Redis的集合和老是须要祈祷客户端能缓存。
正如官方文档解释的那样, "在一个基于端点的API,客户端可以使用HTTP缓存轻易的避免重复获取资源和识别何时两个资源是同样的。客户端能够根据API中的URL做为全局惟一的标识符构建缓存。在GraphQL中,没有相似URL的对象可以做为全局惟一的标识符。最佳实践是提供这么一个标识符供客户端使用"
鉴权问题也是咱们在使用GraphQL时关注的一个重要问题。将GraphQL做为一个特定领域语言考虑,它只是薄薄的一层放置在服务器和客户端中间。鉴权是单独的一层,语言自己并不会对应用进行验证和受权。可是你可使用入口令牌(entry tokens)把客户端和响应关联起来。这与咱们在REST中遵循的方法很是类似。
n+1问题是在作GraphQL后端时最明显的可能遇到的优化问题。
若是你没有优化你的GraphQL查询,你可能在一次query进行屡次查询。没有合适的缓存和批量处理系统,每次肯定字段的时候服务器都会响应一次请求。DataLoader无疑是最好的解决方案,能够极大地加强后端的性能,特别是在GraphQL服务器中。 用一个简单的例子描述n+1问题
query {
users {
name
education {
degree
year
}
age
address {
country
city
street
}
}
}
复制代码
使用REST API是很容易评估,识别和解决n+1问题的。对于GraphQL有所不一样。幸运的是,Facebook正在努力经过DataLoader解决这个问题
DataLoader主要使用了批处理和缓存。它用于批量加载客户端的多个 问题/请求的响应。此外,它能够缓存响应和让它们能响应连续相似的资源请求。
好的,咱们已经强调了一些GraphQL重要的方面。可是要开发一个功能齐全的app,咱们也须要知道一些其余用来加强功能和性能的部分。
正如它的名字,Queries是客户端从服务端获取数据。和从多个端点返回详细信息的REST不同,GraphQL只提供了一个端点,让客户端从预约义的框架决定它须要的数据。 例如:
{
Users {
name
}
}
复制代码
上面的查询提到的'Users'字段称为根字段,其余数据称为载荷。 这个查询将会返回用户名的列表:
{
“Users”: [
{“name”: “Damira”},
{“name”: “Michael”}
{“name”: “Salman”}
{“name”: “Sara”}
{“name”: “Maria”}
]
}
复制代码
值得注意的是,这个查询只返回了用户名(由于在咱们的查询中,咱们只声明了咱们须要用户名)。对于二外的请求,咱们须要为它增长特定的细节。 例如,假设咱们只但愿获取列表中的最后3个用户的信息。咱们能够这么写参数来实现它。
{
Users (last: 3) {
name
username
}}
复制代码
至此,咱们已经看到如何经过查询从服务器获取数据。如今让咱们看一下在GraphQL中建立,省略,更新数据的方法。
Mutations用于建立,更新或者删除数据。除了须要在开头增长‘mutation’ 字段,它的结构和queries几乎同样。例如,
mutation {
createUser (name : “John”, username: ”jo123”){
name
username
}
}
复制代码
Subscriptions用于设置和保存和服务器的实时链接。它可让你获取相关事件的实时信息。大多数状况下,客户端须要订阅特定的事件来获取相应的数据。 请经过graphql.org/learn/queri… 获取详细信息
在Aollo里面的Stack 能够找到一部分问题的解决方案。
若是你有一个正在运行的项目,它是很难快速从RESTful API迁移到GraphQL的。但好消息是你能够同时享受这两种方法的好处。 例如你能够用GraphQL的queries去重构前端里获取数据的方式,而后再开始整合 mutations。它容许你缓慢的减小你的controllers里的actions 此外,你能够在项目中长时间保持两种方法并存。例如,若是你想简化受权机制,你能够一直用REST架构提供帮助。
https://github.com/weblab-technology/graphql-example
REST and Web Services — In Theory and in Practice — Springer
by Oleksandr Knyga, Software Engineer Maksim Kolesnikov, DevOps Sergei Guliaev, Back-End Developer Viacheslav Eremin, Front-End Developer Sharmeen Hayat, author & Data Specialist Dima Dmytriienko, editor & Brand Specialist
原文提到的GraphQL一些问题,在Apollo GraphQL这个项目中都获得了必定程度的解决,比加缓存。