用接口的思想来理解GraphQL

接口是行为的定义,确定了跟系统交互的界面。 行为的实体是函数,函数包括定义和实现,而接口只关注函数的定义。 函数定义包括传人参数和返回值,包含了参数名称和类型,包含了返回值的类型。

GraphQL是接口

GraphQL本质上是一种接口的定义规范,里面包括了种类型定义和函数定义(名称,参数,返回值),可以精确的定义了前后端交互的界面。

GraphQL不是一般的接口

GraphQL是只定义接口,不关心实现,本身是语言不相关的。

这意味着GraphQL可以作为连接不同系统的统一规范。

GraphQL包含严格的类型定义,这种定义可以用来进行代码生成,结合本身有提供很多辅助开发工具,可以辅助解决接口的定义、实现、文档、调试问题。

以上所说的这些,很多rpc平台,像grpc、thrift都能解决。着这个角度讲,GraphQL就是一种rpc协议。

如果要说不同之处,GraphQL设计之处的目的是解决前后端交互的问题。前后端交互网络传输是一个问题。

传统的rpc返回结果的时候回返回完整的数据,但是很多时候我们只需要结果中的部分数据,这样传输无用数据会造成带宽浪费,同时也会影响处理速度,对于响应要求高或者网络带宽不够的应用不利,移动应用就属于这类。

使用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本质上是一种为了解决前后端交互问题二设计的接口协议。很好的解决了接口的定义、文档、调试、使用等问题,目测会越来越火。

猜你喜欢

转载自juejin.im/post/5b5a702b518825068302a0d7
今日推荐