2.3.2 服务器端的Schema

在服务器端,GraphQL与RESTful服务有一个显著的不同。就是GraphQL服务的开发者需要给GraphQL应用服务器提供一套Schema来定义所有的数据类型和查询。换句话说,所有的数据类型和查询都要在这个事先定义的Schema中有据可查。

图2-2展现的是GrpahQL应用服务如何通过Schema来验证客户端发来的请求和返回给客户端的响应。从图中可以看出,验证是双向的,请求和响应都会依照Schema来验证。客户端发送过来的不符合要求的请求会被拒绝,同样地,从数据库或其他服务中获得的不符合要求的数据也不会被返回给客户端。

图2-2 服务器Schema和客户端请求关系图

需要注意的是GraphQL并没有限定数据传输协议和返回数据的格式,当然在现有的几乎所有GraphQL前后端实现中,都是在HTTP协议上使用JSON格式来传输返回数据。但理论上,可以根据自己的需求定义数据传输协议和返回数据的格式,比如采用二进制通信协议的Thrift等技术。

Q&A 在数据查询中,使用一个预先定义的Schema有什么好处?

(1)可以更好地保证数据正确。错误的数据不会进一步传播,产生更严重的业务逻辑问题。

比如有一个提交给服务器的订单,缺失了一些必要数据,没有提供客户ID,这样的数据提交进服务器,如果没有其他验证方式,写入了数据库,就会造成脏数据,往往会带来更大的麻烦。很多读者认为,可以在服务器端写代码验证啊。但客户端并不知道服务器端程序员写了怎么样的验证代码,而Schema是在服务器端和客户端共享的,客户端可以轻易知晓什么字段是必需的,什么字段需要复合什么类型。

(2)Schema定义好后,前后端可以依据Schema分别开发,而无须等待另一边的完成。

在很多公司,前后端开发任务会分发给不同的团队,甚至某些应用的前后端开发会归属不同的公司,这时候跨团队跨公司的实时沟通会比较麻烦,往往需要事先定好一个规则,前端要什么,后端要什么,大家同时按照规则来开发,就不用互相等待对方完成。而这个规则,其实就是Schema。

GraphQL的类型系统也正是通过定义在服务器端的Schema来保证的。在实现中,开发者会在Schema定义所有的自定义类型,例如用户、商品和订单等,来满足应用的需要。在后面的章节中还会看到,其实客户端发送的查询也是一种特殊的自定义类型。