Why GraphQL? 6个问题

GraphQL, 是一个API的标准: specification.

对于每个新技术, 要搞清楚的6个问题:

  • 1.这个技术出现的背景, 初衷, 要达到什么样的目标或是要解决什么样的问题.
  • 2.这个技术的优势和劣势分别是什么, 或者说, 这个技术的trade-off是什么.
  • 3.这个技术使用的场景.
  • 4.技术的组成部分和关键点.
  • 5.技术的底层原理和关键实现.
  • 6.已有的实现和它之间的对比.

1.这个技术出现的背景, 初衷, 要达到什么样的目标或是要解决什么样的问题.

GraphQL是相对于REST API的另一种标准.

相对于REST返回固定结构数据的多个endpoints, GraphQL的server只暴露一个endpoint, 由客户端来规定想要的字段和结构, 服务端精确返回client要求的数据.

初衷和背景

2012年, Facebook有一个新闻类的iOS app. 随着移动用户增多, 网络请求有设备电量消耗, 弱网环境等问题.

这在当时是一个非常紧迫的issue, 于是他们研究出了GraphQL, 减小了需要发送的请求个数和数据传输量.

2015年Facebook将GraphQL开源.

类似的尝试还有Netflix的Falcor和Coursera, 后者后来取消了自己的effort, 加入了GraphQL的阵营.

目标和要解决的问题

GraphQL思想: enables declaratative data fetching.

GraphQL要解决的问题: 优化客户端向服务器请求数据的过程:

  • 对于同样的业务需求, REST API可能要请求多个endpoints, GraphQL可以用一个请求.
  • 数据形式是客户端定义的, 只取想要的数据, 不会取多余的数据, 减小了数据传输量.
  • 各个前端可以访问自己想要的数据.
  • 快速开发, feature快速迭代. 升级改动时, 可能不需要后端改动.

2.这个技术的优势和劣势分别是什么, 或者说, 这个技术的trade-off是什么.

GraphQL的优势

  • 客户端可以精准取到自己想要的数据, 不再多取或者少取. 多取: 取到了不需要的数据, 可能有性能, 流量问题; 少取: 需要多发请求来满足需求.
  • API有strong typed schema. 客户端可以通过schema知道API支持什么, 包括操作, 参数, 可能的响应等. 支持introspection. schema是一个API能力的contract, 不需要再额外写文档, 一旦定义好了之后, 前后端可以独立工作.
  • 强类型, 利用schema, 结合build工具, 可以在编译时期对请求进行一些检查.
  • 有助于产品快速升级迭代. 前端的改动可以不需要后端的修改.
  • 富有洞察力的数据分析: 因为可以精细地知道client要读的数据, 对数据的的使用情况可以有更深的理解. 在API改动的时候可以deprecate掉不用的数据. 也有助于后端的性能分析.
  • schema stitching: 多个不同的GraphQL的endpoints可以组合成为一个.
  • 社区支持好. 多种语言: https://graphql.org/code/#server-libraries; 多种客户端: https://medium.com/open-graphql/exploring-different-graphql-clients-d1bc69de305f; 多种工具: Prisma, GraphQL Faker, GraphQL Playground, graphql-config.

GraphQL的缺点

  • 可能并不适合所有类型的API. 比如认证, 授权(authentication and authorization).
  • 服务器端的性能问题.
  • 服务器端的Cache. 需要一个全局的id, 讨论见: Caching.
  • 通信的快速发展, 实现GraphQL节约的数据传输量可能不值一提, 优势不明显.

3.这个技术使用的场景.

GraphQL是一种规范, 具体实现有多种.

和传输层, 数据库, 数据源类型都不相关.

GraphQL应用场景:

  • 在数据库之上.
  • 和已有系统集成. 可以用来改造遗留系统, 统一接口, 隐藏实现.
  • 混合前两者, 在已有系统和数据库之上.

理想开发场景: 根据数据, 建立好schema之后, 前后端独立开发, 前端可以根据需要拿到想要的数据.

4.技术的组成部分和关键点.

Schema

Schema定义了API的能力, 是server和client之间的协议. 规定了客户端可以请求的数据和类型.

The Schema Definition Language (SDL): Schema Definition Language.

Root Types: Query, Mutation, Subscription.

对应查询, 更改和订阅.

Server端

GraphQL服务器只暴露一个endpoint.

在API的设计上, 需要把数据按照Graph来想, 而不是按照endpoints来想, 更专注于描述数据.

对于Schema定义好的结构, Server端对于每个字段实现resolver function, 进行查询.

Server库: https://graphql.org/code/#server-libraries

Client端

客户端查询, 更加自主的结构, 字段级别的粒度.

Client库: https://graphql.org/code/#graphql-clients

和Server库一样, 这些库为我们封装了一些样板代码, 简化方便了我们的开发.

5.技术的底层原理和关键实现.

Server端实现

  • schema的定义. -> structure.
  • resolver function形式的具体实现. -> behaviour.

queries/mutations都包含一个字段集合.

在server上, 每个字段都有一个resolver function, 用来读取相应字段的数据.

Server上执行的机制:

The query is traversed field by field, executing “resolvers” for each field.

广度优先. 按层级进行.

为了改善效率, JavaScript有dataloader, 把resolver的调用批处理, 减少重复调用.

Client端实现

客户端实际上发送的是POST请求, GraphQL的query作为JSON payload的字段.

可以用curl命令模拟得到相同的效果, 见:

https://graphql.org/graphql-js/graphql-clients/

introspection query可能是唯一的GET请求.

6.已有的实现和它之间的对比.

REST的好点子: stateless servers, structured access to resources.

REST的缺点: 快速变化的客户端需求可能和REST的静态属性不合.

REST:

  • 业务数据不同, 可能需要client向server发送多个请求.
  • 请求中可能包含多余数据. old client也会收到新增的数据.
  • 弱类型.
  • 错误返回不同的状态码.
  • API升级需要提供不同的版本号.

GraphQL更加灵活和有效率.

  • 单个请求.
  • 不包含多余数据.
  • 强类型.
  • 错误返回是在响应中的"errors"字段, 包含错误list, 每个错误有"message"字段.
  • API升级不需要版本号. 新增数据和类型不会影响以前的查询.

REST和GraphQL两者可以共存.

参考

Why GraphQL? 6个问题的更多相关文章

  1. Facebook的Web开发三板斧:React.js、Relay和GraphQL

    2015-02-26 孙镜涛  InfoQ Eric Florenzano最近在自己的博客上发表了一篇题为<Facebook教我们如何构建网站>的文章,他认为软件开发有些时候需要比较大的跨 ...

  2. facebook graphql

    思想先进,前端直接从后台调用所需要的数据. 最简单的理解: 从"select * from 学生表" 进化为"select name, sex from 学生表" ...

  3. Graphql介绍(Introduction to GraphQL)

    Introduction to GraphQL  GraphQL介绍 Learn about GraphQL, how it works, and how to use it in this seri ...

  4. graphql 新API 开发方式

    我们知道 GraphQL 使用 Schema 来描述数据,并通过制定和实现 GraphQL 规范 定义了支持 Schema 查询的 DSQL (Domain Specific Query Langua ...

  5. [GraphQL] Use GraphQLNonNull for Required Fields

    While certain fields in a GraphQL Schema can be optional, there are some fields or arguments that ar ...

  6. [GraphQL] Use Arguments in a GraphQL Query

    In GraphQL, every field and nested object is able to take in arguments of varying types in order to ...

  7. [GraphQL] Write a GraphQL Schema in JavaScript

    Writing out a GraphQL Schema in the common GraphQL Language can work for simple GraphQL Schemas, but ...

  8. [GraphQL] Serve a GraphQL Schema as Middleware in Express

    If we have a GraphQL Schema expressed in terms of JavaScript, then we have a convenient package avai ...

  9. [GraphQL] Use GraphQL's List Type for Collections

    In order to handle collections of items in a GraphQL Schema, GraphQL has a List Type. In this video, ...

  10. [GraphQL] Use GraphQL's Object Type for Basic Types

    We can create the most basic components of our GraphQL Schema using GraphQL's Object Types. These ty ...

随机推荐

  1. Java性能优化,操作系统内核性能调优,JYM优化,Tomcat调优

    文章目录 Java性能优化 尽量在合适的场合使用单例 尽量避免随意使用静态变量 尽量避免过多过常地创建Java对象 尽量使用final修饰符 尽量使用局部变量 尽量处理好包装类型和基本类型两者的使用场 ...

  2. (19)ln命令:在文件之间建立链接(硬链接和软链接)

    1.ext 文件系统(Linux 文件系统)是如何工作的. 我们在前面讲解了分区的格式化就是写入文件系统,而 Linux 目前使用的是 ext4 文件系统.如果用一张示意图来描述 ext4 文件系统 ...

  3. 我们到底为什么要用 IoC 和 AOP

    作为一名 Java 开发,对 Spring 框架是再熟悉不过的了.Spring 支持的控制反转(Inversion of Control,缩写为IoC)和面向切面编程(Aspect-oriented ...

  4. 2019牛客暑期多校训练营(第五场)H.subsequence 2(拓扑)

    题意:给你一个字符串的长度n 现在询问了m*(m-1)/2次 每次都可以询问两个字符 然后 会告诉你只留下这两个字符后 字符串的样子 现在问你能不能还原字符串 如果能就输出字符串 否则输出-1 思路: ...

  5. 【uva 534】Frogger(图论--最小瓶颈路 模版题)

    题意:平面上有N个石头,给出坐标.一只青蛙从1号石头跳到2号石头,使路径上的最长便最短.输出这个值.(2≤N≤200) 解法:最小瓶颈树.而由于这题N比较小便可以用2种方法:1.最短路径中提到过的Fl ...

  6. 牛客NC15879 A Simple Problem

    传送门:A Simple Problem 题意 给定两个序列s1和s2,同样的数字可以用相同的别的数字代替(并且也可以是出现过的数字),问s2在s1中出现了几次. 题解 首先预处理一下这两个序列,因为 ...

  7. Codeforces Round #613 (Div. 2) C. Fadi and LCM(LCM & GCD)

    题意: LCM(a, b) = X,求 max(a, b) 的最小值. 思路: a, b 只可能存在于 X 的因子中,枚举即可. #include <bits/stdc++.h> usin ...

  8. codeforces578C. Weakness and Poorness

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  9. Java15 运行Hello,world竟然不用javac?

    喜欢尝鲜的我,装好了Java15,如下编写了一个输出语句:hello,world. 当我打开cmd准备运行的时候,惊呆了! 以前java8的时候不都是这样操作的吗?最初以为环境配置问题,可以即便在系统 ...

  10. [Golang]-3 函数、多返回值、变参、闭包、递归

    // test01 project main.go package main import ( "fmt" ) // 单返回值的函数 func plus(a int, b int) ...