GraphQL应用的基本架构
下图是一个 GraphQL 应用的基本架构,其中客户端只和 GraphQL 层进行 API 交互,而 GraphQL 层再往后接入各种数据源。这样一来,只要是数据源有的数据, GraphQL 层都可以让客户端按需获取,不必专门再去定接口了。
GraphQL应用基本架构
一个GraphQL服务仅暴露一个 GraphQL Endpoint,可以按照业务来进行区分,部署多个GraphQL服务,分管不同的业务数据,这样就可以避免单服务器压力过大的问题了。
GraphQL特点总结
- 声明式数据获取(可以对API进行查询): 声明式的数据查询带来了接口的精确返回,服务器会按数据查询的格式返回同样结构的 JSON 数据、真正照顾了客户端的灵活性。
- 一个微服务仅暴露一个 GraphQL 层: 一个微服务只需暴露一个GraphQL endpoint,客户端请求相应数据只通过该端点按需获取,不需要再额外定义其他接口。
- 传输层无关、数据库技术无关: 带来了更灵活的技术栈选择,比如我们可以选择对移动设备友好的协议,将网络传输数据量最小化,实现在网络协议层面优化应用。
Part 2 Schema & Type
GraphQL支持的数据操作
GraphQL对数据支持的操作有:
- 查询(Query): 获取数据的基本查询。
- 变更(Mutation): 支持对数据的增删改等操作。
- 订阅(Subscription): 用于监听数据变动、并靠websocket等协议推送变动的消息给对方。
GraphQL支持的操作
GraphQL的核心概念:图表模式(Schema)
要想要设计GraphQL的数据模型,用来描述你的业务数据,那么就必须要有一套Schema语法来做支撑。
想要描述数据,就必须离不开数据类型的定义。所以GraphQL设计了一套Schema模式(可以理解为语法),其中最重要的就是数据类型的定义和支持。
那么类型(Type)就是模式(Schema)最核心的东西了。
什么是类型?
- 对于数据模型的抽象是通过类型(Type)来描述的,每一个类型有若干字段(Field)组成,每个字段又分别指向某个类型(Type)。这很像Java、C#中的类(Class)。
- GraphQL的Type简单可以分为两种,一种叫做Scalar Type(标量类型),另一种叫做Object Type(对象类型)。
那么就分别来介绍下两种类型。
标量类型(Scalar Type)
标量是GraphQL类型系统中最小的颗粒。类似于Java、C#中的基本类型。
其中内建标量主要有:
- String
- Int
- Float
- Boolean
- Enum
- ID
Scalar Type
上面的类型仅仅是GraphQL默认内置的类型,当然,为了保证最大的灵活性,GraphQL还可以很灵活的自行创建标量类型。
对象类型(Object Type)
仅有标量类型是不能满足复杂抽象数据模型的需要,这时候我们可以使用对象类型。
通过对象模型来构建GraphQL中关于一个数据模型的形状,同时还可以声明各个模型之间的内在关联(一对多、一对一或多对多)。
对象类型的定义可以参考下图:
对象模型引入关联关系
是不是很方便呢?我们可以像设计类图一样来设计GraphQL的对象模型。
类型修饰符(Type Modifier)
那么,类型系统仅仅只有类型定义是不够的,我们还需要对类型进行更广泛性的描述。
类型修饰符就是用来修饰类型,以达到额外的数据类型要求控制。
比如:
- 列表:[Type]
- 非空:Type!
- 列表非空:[Type]!
- 非空列表,列表内容类型非空:[Type!]!
在描述数据模型(模式Schema)时,就可以对字段施加限制条件。
例如定义了一个名为User的对象类型,并对其字段进行定义和施加限制条件:
User字段控制
那么,返回数据时,像下面这种情况就是不允许的:
错误的表示
Graphql会根据Schema Type来自动返回正确的数据:
正确的表示
其他类型
除了上面的,Graphql还有一些其他类型来更好的引入面向对象的设计思想:
接口类型(Interfaces): 其他对象类型实现接口必须包含接口所有的字段,并具有相同的类型修饰符,才算实现接口。
比如定义了一个接口类型:
那么就可以实现该接口:
联合类型(Union Types): 联合类型和接口十分相似,但是它并不指定类型之间的任何共同字段。几个对象类型共用一个联合类型。
输入类型(Input Types): 更新数据时有用,与常规对象只有关键字修饰不一样,常规对象时 type 修饰,输入类型是 input 修饰。
比如定义了一个输入类型:
前端发送变更请求时就可以使用(通过参数来指定输入的类型):
所以,这样面向对象的设计方式,真的对后端开发人员特别友好!而且前端MVVM框架流行以来,面向对象的设计思想也越来越流行,前端使用Graphql也会得心应手。
Part 3 GraphQL技术接入架构
Graphql 技术接入架构
那么,该怎么设计来接入我们现有的系统中呢?
将Graphql服务直连数据库的方式: 最简洁的配置,直接操作数据库能减少中间环节的性能消耗。
直连数据库的接入
集成现有服务的GraphQL层: 这种配置适合于旧服务的改造,尤其是在涉及第三方服务时、依然可以通过原有接口进行交互。
集成现有服务的GraphQL层
直连数据库和集成服务的混合模式: 前两种方式的混合。
混合接入方式
可以说是非常灵活了!你都不用担心会给你带来任何的麻烦。
服务端实现
在服务端, GraphQL 服务器可用任何可构建 Web 服务器的语言实现。有以下语言的实现供参考:
C# / .NET、Clojure、Elixir、Erlang、Go、Groovy、Java、JavaScript、Julia、Kotlin、Perl、PHP、Python、R、Ruby、Rust、Scala、Swift... 种类繁多,几乎流行的语言都有支持。
客户端实现
在客户端,Graphql Client目前有下面的语言支持:C# / .NET、Clojurescript、Elm、Flutter、Go、Java / Android、JavaScript、Julia、Swift / Objective-C、iOS、Python、R。覆盖了众多客户端设计语言,而其他语言的支持也在推进中。