接口是行为的定义,肯定了跟系统交互的界面。 行为的实体是函数,函数包括定义和实现,而接口只关注函数的定义。 函数定义包括传人参数和返回值,包含了参数名称和类型,包含了返回值的类型。后端
GraphQL是接口网络
GraphQL本质上是一种接口的定义规范,里面包括了种类型定义和函数定义(名称,参数,返回值),能够精确的定义了先后端交互的界面。函数
GraphQL不是通常的接口 工具
GraphQL是只定义接口,不关心实现,自己是语言不相关的。开发工具
这意味着GraphQL能够做为链接不一样系统的统一规范。spa
GraphQL包含严格的类型定义,这种定义能够用来进行代码生成,结合自己有提供不少辅助开发工具,能够辅助解决接口的定义、实现、文档、调试问题。设计
以上所说的这些,不少rpc平台,像grpc、thrift都能解决。着这个角度讲,GraphQL就是一种rpc协议。调试
若是要说不一样之处,GraphQL设计之处的目的是解决先后端交互的问题。先后端交互网络传输是一个问题。code
传统的rpc返回结果的时候回返回完整的数据,可是不少时候咱们只须要结果中的部分数据,这样传输无用数据会形成带宽浪费,同时也会影响处理速度,对于响应要求高或者网络带宽不够的应用不利,移动应用就属于这类。cdn
使用GraphQL接口时,能够基于定义约定想要的东西,而后GraphQL会根据请求,只返回想要的数据,这点相似于SQL。同时,能够在一次GraphQL请求发送多个函数调用请求,这样能够减小请求的发送量,从而提升响应速度。
举例说明
下面咱们用Go语言定义了一个简单的类型和接口。
// 定义的User类型
type User struct {
ID int
Name string
Age int
Posts []Post
}
type Post struct {
ID int
Title string
Owner User
}
// 定义的查询接口
type Query interface {
FetchUsers() []User
FetchPosts(userID int) []Post
GetUserById(id int) *User // 定义了函数的参数和返回值
}
// 定义的修改接口
type Mutation interface {
CreateUser(name string, age int) User
DeleteUser(id int) *User
}
复制代码
咱们知道,接口若是成功调用,会返回一个完整的数据。好比,GetUserById成功调用后会返回一个完整的User给咱们。 这里包括大量User的所有属性, 形如User {ID: 0, Name: "Alex", Age: 28}。 可是若是咱们带宽太窄,只须要User的Name信息呢? 这里就是graphql跟接口不一样的地方。像SQL同样,使用GraphQL你能够声明你须要什么属性。
{
GetUserById(id: 1) {
Name
}
}
复制代码
接口,你调用一个函数,返回一个结果。你返回多种结果,调用屡次函数。 使用GraphQL,你可以把多个对数据的要求放在一个请求里面。
{
GetUserById(id: 1) {
Name
}
FetchPosts(userId: 1) {
title
}
}
复制代码
并且,GraphQL还支持顺着类型定义嵌套的抓取信息。 上面的查询也能够写成下面的形式。
{
GetUserById(id: 1) {
Posts {
title
}
}
}
复制代码
固然你也能够丧心病狂的不断嵌套抓取数据。
{
GetUserById(id: 1) {
Posts {
title
Owner {
Name {
Posts {
title
...
}
}
}
}
}
}
复制代码
这种按照接口的类型定义,不断嵌套的抓取数据正是GraphQL中Graph的由来,表达了Graph + QL = 按图 + 索骥内涵。 固然这种变态的抓取是很是恐怖的,若是有坏人故意发这种请求搞死咱们,咱们就完了,因此必须有一种方式来限制这种行为。 好在,咱们能够对用户的请求进行AST语法分析,限制嵌套的深度,好比,咱们可让你最多嵌套3层。
总结
GraphQL本质上是一种为了解决先后端交互问题二设计的接口协议。很好的解决了接口的定义、文档、调试、使用等问题,目测会愈来愈火。