-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
掌握甩锅技术: Typescript 运行时数据校验 #13
Comments
6666666666666 |
json schema + swagger貌似还不错 |
class-validator会不会是一个更好的解决方案? class-validator,json schema,io-ts这三者有什么优缺点 |
class-validator 要多写很多 class-validator 装饰器。 |
如果要限制一个数的范围,该怎么实现呢,像joi可以这样: |
这文笔爱了爱了,什么时候出书,必买一本 |
及时雨呀~ |
zod.js |
从内容到形式,我觉得可以做朋友了 |
直接用grpc |
背景
大家出来写
Bug代码的,难免会出 Bug。文章背景就发生在一个 Bug 身上,
有一天,测试慌张中带着点兴奋冲过来:
![image](https://user-images.githubusercontent.com/13402013/56365430-6d619580-6223-11e9-82b2-2a91a1abddb0.png)
测试:"xxx系统前端线上出 Bug 了,点进xx页面一片空白啊"。
我:"纳尼?我写的Bug怎么会出现代码呢?"。
虽然大脑一片空白,但是锅还是要背的。
进入页面一看,哦豁,完蛋,
cannot read the property 'xx' of undefined
。确实是前端常见的报错呀。背锅王,我当定了?未必。
我眉头一皱,发现事情并不是那么简单,经过一番猛如虎的操作之后,最终定位到问题是:后端接口响应的 JSON 数据中,一个嵌套比较深的字段没有返回,即前端只读到了
undefined
。咱按章程办事,后端提供的接口文档指定了数据结构,那你没有返回正确数据结构,这就是你后端的锅,虽然严谨点前端也能捕获到错误进行处理,但归根到底,是你后端数据接口处理有问题,这锅,我不背。
甩锅又是一门扯皮的事情,杀敌一千自伤八百,锅已经扣下来了,想甩出去就难咯,。
唉,要是在接口出错的时候,能立刻知道接口数据出问题,先发制人,马上把锅甩出去那就好咯。
这就是本文即将要讲述的 "Typescript 运行时数据校验"。
为什么要运行时校验数据?
众所周知,
Typescript
是JavaScript
超集,可以给我们的项目代码提供静态类型检查,避免因为各种原因而未及时发现的代码错误,在编译时就能发现隐藏的代码隐患,从而提高代码质量。但是,
TypeScript
项目的一个常见问题是: 如何验证来自外部源的数据并将验证的数据与TypeScript类型联系起来。 即,如何避免后端 API 返回的数据与Typescript
类型定义不一致导致的运行时错误。Typescript
能用于运行时校验数据类型,那么有没有一种方法,能让我们在 运行时 也进行Typescript
数据类型校验呢?io-ts 解决方案?
业界开源了一个运行时校验的工具库:io-ts。
但是,如上面的代码所示,这工具看起来就有点啰嗦有点难用,对代码的侵入性非常强,要全盘依据它的语法来重写代码。这对于一个团队来说,存在一定的迁移成本。
而我们更希望做到的理想方案是:
写好接口的数据结构
typescript
定义,不需要做太多的额外变动,直接就能校验后端接口响应的数据结构是否符合typescript
接口定义理想方案探索
首先,我们了解到,后端响应的数据接口一般为
JSON
,那么,抛开Typescript
,如果要校验一个 JSON 的数据结构,我们可以怎么做到呢?答案是
JSON schema
。JSON schema
JSON schema 是一种描述 JSON 数据格式的模式。
例如 typescript 数据结构:
等价于以下的 json schema :
根据已有
json-schema
校验库,即可校验数据对象这里大家可能就又会困惑:这
json-schema
写起来也太费劲了?还不一样要学习成本,那和io-ts
有什么区别。但是,既然我们同时知道
typescript
和json-schema
的语法定义规则,那么就两者必然能够互相转换。也就是说,即便我们不懂
json-schema
的规范与语法,我们也能通过typescript
转化生成json-schema
。那么,在以上的前提下,我们的思路就是:既然
typescript
本身不支持运行时数据校验,那么我们可以将typescript
先转化成json schema
, 然后用json-schema
校验数据结构typescript -> json-schema
要将
typescript
声明转换成json-schema
,这里推荐使用 typescript-json-schema。我们可以直接使用它的命令行工具,这里就不仔细展开说明了,感兴趣的可以看下官方文档:
github 上也有所有类型转换的 测试用例,可以对比看看
typescript
和 转换出的json-schema
结果json-schema 校验库
利用
typescript-json-schema
工具生成了json-schema
文件后,我们需要根据该文件进行数据校验。json-schema
数据校验的库很多,ajv,jsonschema 之类的,这里用jsonschema
作为示例。当我们校验以下数据时:
完全例子请看 github
配合上前端上报系统,当线上系统接口返回了非预料的数据,导致出 bug,就可以实时知道到底错在哪了,并且及时甩锅给后端啦。
commit 时自动更新 json-schema
前面提到,我们需要执行
typescript-json-schema <path-to-typescript-files-or-tsconfig> <type>
命令来声明 typescript 对应的json-schema
文件。那么,这里就有个问题,接口数量有可能增加,接口数据也有可能变动,那也就代表着,我们每次变更接口数据结构,都要重新跑一下
typescript-json-schema
,时刻保持json-schema
和 typescript一一对应。这我们就可以用 husky 的
precommit
, 加上 lint-staged 来实现每次更新提交代码时,自动执行typescript-json-schema
,无需时刻关注 typescript 接口定义的变更。完全例子请看 github
总结
综上,我们实现了
typescript
声明文件 转换生成json-schema
文件husky
+lint-staged
每次提交代码自动执行 步骤1,保持git 仓库的代码typescript
声明 和json-schema
时刻保持一致。那么,当 Bug 出现的时候,你甚至可以在测试都还没发现这个 Bug之前,就已经把锅甩了出去。
只要你跑得足够快,Bug 就会追不上你。
The text was updated successfully, but these errors were encountered: