写点什么

GraphQL 设计思想

用户头像
Ryan Zheng
关注
发布于: 1 小时前

Graphql 的核心思想是把应用层当成数据库来用。

以往 Rest 构架



有多个 Controller, Facade,Services, DAO。每一个 Controller 负责不一样的 Request Mapping。Facade 的功能更多的是做 DTO 和 DAO 的数据转换。Services 层我们处理的是 DAO,Controller 层处理 DTO, DTO 是用户需要的数据, DAO 对应数据库的数据。

GraphQL 构架


If you look at the picture, Graphql replaces the previous controllers with only one endpoint. DefaultGraphQLServlet. It constructs a type-> resolver mapping during schema parsing. In runtime, Graphql calls the correct resolver(Query or Mutation) which in turns calls the business services.


理解 Graphql 的内部实现可以拿数据库来做类比。我们在创建数据库的表的时候

exit: Ctrl+↩

CREATE TABLE table_name (    column1 datatype,    column2 datatype,    column3 datatype,   ....);
复制代码

数据库没有具体的类与之对应,数据库也需要创建一个 Object 来表示这个表的结构和属性。表示方法可以是

exit: Ctrl+↩

Class Table {  name: String  Map<String, String> columns}
复制代码


Graphql 的类型定义通过 schema.graphqls 文件来定义的。Graphql Tools Jar 提供了方法来 Parse 这些文件中 Schema 的定义,根据文件内部创建啦多个 GraphqlObjectType 的类,类似于数据库的表的结构。这种定义方法叫做 Metadata 定义,好处是可以动态的实现任何类型的定义,而不需要写 Java 实体类与之对应。(反过来想 ORM 做的实际上是定义实体类,然后转换成 Metadata 定义)。


数据库分为两种操作查询和修改。Graphql 也类似,提供查询和修改。查询是提供给前台有哪些可以被查询的 fields。修改提供给前台有哪些可修改的操作。比如说数据库有一个 User,在数据库可以插入一条 User 记录,也可以 Update 已经存在的 User 记录。

Graphql 开发

1、在.graphqls 文件中定义需要的数据类型。这个数据类型就提供了前台能查询和修改的数据字段。比如在数据库中我们首先定义 User 表,这个表有十个字段,但是 Select 语句可以只查询两个字段。select name, age from User。 Graphql 同样提供给了前台这样的塞选返回哪些数据的功能,不再是后来决定返回多少个。

exit: Ctrl+↩

type User {    num:String!    phone:String    gender:Int!}
复制代码

2、有了需要的类型和对应的属性后,接下来定义该类型所支持的查询和修改操作。(想想数据库的对应)

查询:

exit: Ctrl+↩

type UserQuery extend type Query{    userDetails(userId: ID!): User!}
复制代码


修改

exit: Ctrl+↩

type UserMutation extend type Mutation {    changeUserName(userId: ID!, name: String): User!    }
复制代码


GraphQL 框架在项目启动的时候,会扫描 Classpath 上所有.graphqls 文件中定义的类型。当 Graphql 看到 UserQuery 定义的时候,会去 Classpath 找 UserQuery 的类。这个类必须实现 GraphqlQueryResolver 接口。对于 Mutation 是一样的。

Graphql 是如何在前台被使用来按需取值的

前面我们定义了 User 的类型,User 包含三个字段。User 类型支持搜索 userDetails 这个搜索方法。这个方法的返回是 User,

前台的 Request

exit: Ctrl+↩

query UserDetails {    userDetails(userId:"2349084324q3F) {        name // i only want name field    }}
复制代码

前台 Request 只需要 name field, 这个 Request 被 Graphql 后台收到以后会找到对应的 UserQuery java 类,然后调用 userDetails 的方法。这个方法的返回值是整个 User 的信息。包含啦其他字段。这个地方用户只需要 name, Graphql 只会把 User.name 返回给前台用户。(可以和数据库 Select 做对比,Graphql 提供给前端的功能像是提供了数据库的 Select 语句一样的东西),只是这种功能在是在和前台交互,像不像是把应用层当成数据库来操作啦)

发布于: 1 小时前阅读数: 8
用户头像

Ryan Zheng

关注

还未添加个人签名 2021.01.18 加入

还未添加个人简介

评论

发布
暂无评论
GraphQL设计思想