![b2273a2d8f53e531f319ff92113726ab.png](https://img-blog.csdnimg.cn/img_convert/b2273a2d8f53e531f319ff92113726ab.png)
本文预期读者阅读过笔者之前的两篇文章
system error:【第十期】基于 Apollo、Koa 搭建 GraphQL 服务端zhuanlan.zhihu.com![5b7474e0511d2680a789ae17d97f0d07.png](https://img-blog.csdnimg.cn/img_convert/5b7474e0511d2680a789ae17d97f0d07.png)
和
system error:【第十一期】实现 Javascript 版本的 Laravel 风格参数验证器zhuanlan.zhihu.com![6383312a26c8e03306804ee85866408a.png](https://img-blog.csdnimg.cn/img_convert/6383312a26c8e03306804ee85866408a.png)
或对 GraphQL
与 Laravel
的验证器有所了解。
前面两篇文章分别讲解了:
- 如何搭建一个
GraphQL
服务器 - 如何实现一个
Laravel
风格的验证器
今天我们来尝试将二者结合,在 GraphQL
工程中实现一个 Laravel
风格的高级验证器。
需求
一个 GraphQL
请求,会经历三个阶段:
- 解析阶段(
Parse phase
) - 验证阶段(
Validation phase
) - 执行阶段(
Execution phase
)
其中,在验证阶段(Validation phase
),会根据 GraphQL SDL
的类型系统,对参数进行基本校验:
- 客户端传递未定义的查询字段,会在验证阶段失败
- 客户端传递与预期类型不匹配的参数,会在验证阶段失败
- 客户端没有传递必传参数,会在验证阶段失败
但是,对于一些稍复杂场景,类型系统的功能无法覆盖到:
- 对某些数字类型的字段,限制上限和下限。例如:年龄,限制在 0 到 150 之间
- 对某些日期类型的字段,限制一个时间区间;例如:出生日期,限制在 1900 年到 2020 年之间
- ......
因此,我们针对更加复杂一些的校验规则,需要一个更高级的验证器。
设计
确定了需求,我们来看如何实现这个高级验证器。
预想中的方案
我们知道自定义标量(custom scalar
)可以限制一个字段值的类型,因此在标量上做高级验证器是个不错的开始。
例如:对于年龄字段,我们新设计一个名为 age
的标量,限制它的取值范围为 0 到 150 之间。对于出生日期字段同理:birthDay
。
但是,这么做有一个问题:我们的字段类型各种各样,没个尽头,如果为每一个类型的字段都设计一个标量,那么我们将被迫维护数量庞大的标