本文是对 Why we used GraphQL for our API的翻译,若有侵权等其余问题,请联系笔者删除。
最近在 Mavel 咱们发布了 Platform API,咱们想利用整合的力量,将这个力量直接放入天天使Marvel 的人们的创意社区中,所以咱们能更加无缝地工做-与平常服务工具一块儿工做。react
什么是一个好的APIweb
若是咱们曾经写过一个好的 API,首先咱们须要想一想什么是一个好的 API。所以咱们肯定了设计任何 API 的良好实践,不管是不是在网络上。json
即便是最改变生活的工具,我不能发现如何去使用,对于本身而言都是无用的。api
没必要要的复杂是为了官僚,咱们老是更喜欢简单浏览器
由于一些事情用你没有预料的的方式运做,或者由于没有预料到的反作用被抓到是很差玩的。事情应该尽量的简单明了。服务器
咱们能够考虑归档出这些点做为开发者体验。这对咱们是用意义的--当咱们设计app或者web界面,咱们会尽可能去保持用户体验。API是针对开发者特定的界面,咱们也应该作一样的事情。网络
其余的APIs哪里有欠缺app
没有标准化编辑器
过去五年大多数的web APIs是REST(ish)和json,而不是稍微有点老的SOAP,RPC,或者自定义的XML。一般,这被视为一件好事,咱们看到了APIs的激增,因为设备更加智能和服务已经开始更加紧密的协同工做。工具
问题是虽然json已经变成web APIs之间发送数据的标准,可是每一个API因为其独一无二的结构和能力,而且没有标准的方式去描述自身。当每一个API和最后一个不一样时,没法构建适合全部的工具。
所以尽管大家正在使用的API或者一些便利的工具,如:编辑器集成工具或者客户端库,可能很完美的被良好的文档支持。
您习惯性地使用的工具可能没法使用您正在使用的API,或者,若是有的话,过于通用,帮助您解决问题独特的部分。事实上,这意味着您没有任何工具。
移动网络和设备
随着愈来愈多的网络流量被过渡到移动设备,产生了另个一个问题。移动端设备位于好延迟低带宽的不可靠的网络上。
REST API一般要求客户端命中多端去收集呈现视图的多种资源数据(例:在两个单独的调用去获取用户的配置文件和喜欢的菜单)
由于移动端网络比其余网络更不可靠,所以当发送多个请求的时候失败的几率更高。这可能使得您获取到部分数据而不能渲染视图,或者渲染占位符当您去从新请求的时候。
与此一样糟糕的是,网络延迟是一个大的性能杀手。延迟是两个设备之间传送数据的时间,好比您的手机和Marvel的服务器。当设备和服务器之间的延迟是50ms,意味着数据从设备到服务器间传送须要50ms,RTT(往返时间)是100ms.100ms听起来不算长,可是您必须考虑到发送单个请求不止一次往返。当您接收数据或者发送数据以前,须要进行DNS查询,TLS加密握手以及TCP三次握手,这些都须要一次或者屡次往返。咱们使用的在网络上传输字节的TCP协议也须要不断的确认收到的数据, 确保丢失的包能够重传。使人悲伤的是,这些确认遵循物理规律,也须要花费往返时间,
这给整个网路设置了一个上限,它直接与网络延迟紧密相关。
在高延迟的网络中,发送一个包往返时间可能须要1s或者更长的时间。网络延迟极大的超出了app开发者的控制,所以咱们须要减小请求来尽量减小它的影响。
另外一个对移动端不成比例地对移动端设备影响的问题是过分获取。一般一端返回资源的完整表示,但颇有可能客户端不必定须要或者想要全部数据,大多数时候须要的是这些数据的子集。尽管如此,服务器仍旧发送无关的数据,而且客户端对这件事没有发言权。
从API端点获取数据的时,颇有可能客户端不想要或须要返回的全部数据,可是仍旧须要支付传送和处理的费用,浪费了带宽和CPU周期,形成更长的响应时间,没有任何好处。
这些问题的解决方式是什么
有一些开源项目试图去解决REST APIs的一些问题,亦即 swagger(OpenAPI)和 API Blueprint。对于swagger 咱们已经有了一点内部经验(可是不是特别开心,yaml多是地狱),并向咱们现有的API添加新端的时候试用API BluePrint,可是发如今 MSON中的小的错误很难被追踪(并不比yaml好多少)。
尽管这些工具的承诺是很好,他们有一件事情作对了:它们强迫您为API定义一个模式,这个模式好像是系统边界文档同样,系统边界一般是最能感觉到集成痛苦的地方。一旦你获取到一个模式,你能用它作各类各样酷炫的东西:生成文档页面,启动模拟服务器进行开发,若是你有倾向,甚至能生成客户端API代码。由于模式是被标准方式具体化的,所以API构建工具是很容易在使用相同标准的API之间进行移植,由于一切都是提早定义的,你的API消费者确切地知道他们的指望是什么以及对您的指望是什么。
这也正是GraphQL作正确的事情,GraphQL定义包含客户端可用全部数据类型、更改和查询的模式。这样每一个人都知道他们的立场。我能马上确切地明白我能获取那种操做,它们接受那种类型做为输入,返回那种类型做为输出。
尽管 swagger和API Blueprint在请求和响应体中携带一个模式,可是它们不能处理过分获取和发送多个请求的问题。若是您将在您的API中解决这些问题,那么它将是自定义的、非标准的、是单个API独有的。一般,您最终会为特定端点编写视图。对于前面提到的例子,这意味着有一端会马上返回用户和菜单数据。那只是单个视图,在您的应用中有多少个独特的视图?这可能会变得混乱。
那么为何是GraphQL
不想REST,GraphQL的核心思想与解决这些问题紧密相关。每次调用仅仅返回在此次请求特定的数据,这有一些好处。首先,彻底经过放在客户端手中,解决了过分请求的问题。第二,它经过须要客户端马上请求它们所须要的数据移除了屡次请求的需求。这种方式的第三个优势是,它容许咱们做为API的操做者去确切的查看谁正在请求每一个字段的人,这使得咱们随着时间的流逝更容易弃用有一些字段,让新的集成商不去使用,而且返回全部存在的集成的列表,而且与他们取得联系提供升级路径。
正如我前面提到的,工具也是咱们考虑的一个因素,全部上述被说起的解决方案有一些相同的工具和相对健康的社区,可是GraphQL超越了其余两个。Gra主要被很是大很活跃的react社区。这意味着大量优秀的工具使得开发者的体验尽量的好。
好比,链接您的编辑器到模式,对您的查询划线,在您有机会以前它们以前对错误进行标注,将其与自动完成功能相集成,当您输入的时候,能为您提供一些建议。
我喜欢的工具之一的是GraphiQL,这是一个为浏览器中运行的GraphQL APIs 构建的IDE。正以下图您看到的,GraphiQL给您提供编地方去写查询(具备您期待的功能:语法高亮,自动补全),查看结果和参考文档。
它基于浏览器意味着咱们可以把它放在任何公共的地方(如Mavel所作的那样)而且容许某人马上在友好的开发环境中获取咱们的API。事实证实是一个有效的方式去控制GraphQL自己以及API的细节,真正地帮助人们开始去运行。
除了它带来的其余好处以外,这也是咱们选择使用GraphQL的缘由,它简单的运行咱们提供比其它替代方案更好的开发者体验。