egg-typebox-validate
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -1,2 +0,2 @@ | ||
import Ajv, { Schema } from 'ajv/dist/2019'; | ||
import { Schema } from 'ajv/dist/2019'; | ||
@@ -7,4 +7,3 @@ declare module 'egg' { | ||
tValidateWithoutThrow: (schema: Schema, data: unknown) => boolean; | ||
getAjv: () => Ajv; | ||
} | ||
} |
{ | ||
"name": "egg-typebox-validate", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "another validate for typescript egg projects", | ||
@@ -51,3 +51,3 @@ "eggPlugin": { | ||
"engines": { | ||
"node": ">=10.0.0" | ||
"node": ">=14.0.0" | ||
}, | ||
@@ -60,7 +60,7 @@ "scripts": { | ||
"test-local": "egg-bin test", | ||
"benchmark": "node ./benchmark/ajv-vs-paramter.mjs", | ||
"benchmark": "node ./benchmark/ajv-vs-parameter.mjs", | ||
"cov": "egg-bin cov", | ||
"lint": "eslint . --ext .ts", | ||
"lint": "eslint app --ext .ts", | ||
"ci": "npm run lint && npm run cov", | ||
"prepublishOnly": "npm run build" | ||
"prepublishOnly": "npm run clean && npm run build" | ||
}, | ||
@@ -76,3 +76,3 @@ "files": [ | ||
}, | ||
"version": "10, 14" | ||
"version": "14" | ||
}, | ||
@@ -79,0 +79,0 @@ "repository": { |
@@ -6,3 +6,2 @@ # egg-typebox-validate | ||
[![Test coverage][codecov-image]][codecov-url] | ||
[![David deps][david-image]][david-url] | ||
[![Known Vulnerabilities][snyk-image]][snyk-url] | ||
@@ -87,4 +86,4 @@ [![npm download][download-image]][download-url] | ||
+ id: Type.String(), | ||
+ name: Type.String(), | ||
+ timestamp: Type.Integer(), | ||
+ name: Type.Optional(Type.String()), | ||
+ timestamp: Type.Optional(Type.Integer()), | ||
+ }); | ||
@@ -118,3 +117,3 @@ // 直接校验 | ||
```js | ||
npm i egg-typebox-validate -D | ||
npm i egg-typebox-validate -S | ||
``` | ||
@@ -139,2 +138,12 @@ | ||
// 写在 controller 外面,静态化,性能更好,下面有 benchmark | ||
+ const paramsSchema = Type.Object({ | ||
+ id: Type.String(), | ||
+ name: Type.String(), | ||
+ timestamp: Type.Integer(), | ||
+ }); | ||
// 可以直接 export 出去,给下游 service 使用 | ||
+ export type ParamsType = Static<typeof paramsSchema>; | ||
class HomeController extends Controller { | ||
@@ -144,11 +153,6 @@ async index() { | ||
+ const paramsSchema = Type.Object({ | ||
+ id: Type.String(), | ||
+ name: Type.String(), | ||
+ timestamp: Type.Integer(), | ||
+ }); | ||
// 直接校验 | ||
+ ctx.tValidate(paramsSchema, ctx.params); | ||
// 不用写 js 类型定义 | ||
+ const params: Static<typeof paramsSchema> = ctx.params; | ||
+ const params: ParamsType = ctx.params; | ||
@@ -233,6 +237,4 @@ ... | ||
但是 parameter 跑了 [benchmark](./benchmark/ajv-vs-paramter.mjs) 后,它完败(不是一个数量级的),毕竟底层实现是完全不一样的,一个是按标准 json-schema 规范去做解析的,另一个是轻量简单处理。 | ||
结论是在静态化的场景下,ajv 的性能要比 parameter 好得多,快不是一个数量级,详见[benchmark](./benchmark/ajv-vs-parameter.mjs) | ||
对于最简单的 case: | ||
```js | ||
@@ -248,6 +250,9 @@ suite | ||
}) | ||
.add('#ajv define once', function() { | ||
ajv.validate(typeboxRule, DATA); | ||
}) | ||
.add('#parameter', function() { | ||
const rule = { | ||
name: 'string', | ||
description: | ||
description: { | ||
type: 'string', | ||
@@ -260,2 +265,5 @@ required: false, | ||
}) | ||
.add('#parameter define once', function() { | ||
p.validate(parameterRule, DATA); | ||
}) | ||
``` | ||
@@ -266,16 +274,14 @@ | ||
```bash | ||
#ajv x 728 ops/sec ±6.82% (73 runs sampled) | ||
#parameter x 2,699,754 ops/sec ±2.30% (86 runs sampled) | ||
Fastest is #parameter | ||
#ajv x 941 ops/sec ±3.97% (73 runs sampled) | ||
#ajv define once x 17,188,370 ops/sec ±11.53% (73 runs sampled) | ||
#parameter x 2,544,118 ops/sec ±4.68% (79 runs sampled) | ||
#parameter define once x 2,541,590 ops/sec ±5.34% (77 runs sampled) | ||
Fastest is #ajv define once | ||
``` | ||
翻译一下就是: | ||
- ajv 每跑一次大概是 1.3ms | ||
- parameter 每跑一次大概是 0.0003ms | ||
## 从 egg-validate 迁移到这个库的成本 | ||
1. 会有 1ms 左右的性能损耗。但不管怎么说,ajv 是 node 最快的 json-schema validator 了。 | ||
2. 把原来字符串式 js 对象写法迁移到 typebox 的对象写法。typebox 的写法还算简单和容易举一反三。 | ||
1. 把原来字符串式 js 对象写法迁移到 typebox 的对象写法。typebox 的写法还算简单和容易举一反三 | ||
2. 把 `ctx.validate` 替换成 `ctx.tValidate` | ||
3. 建议渐进式迁移,先迁简单的,对业务影响不大的 | ||
@@ -286,5 +292,4 @@ ## 总结 | ||
1. 可以解决 ts 项目中参数校验代码写两遍类型的问题,提升代码重用率,可维护性等问题。 | ||
2. 用标准 json-schema 来做参数校验,内置更多类型 | ||
3. 建议渐进式迁移,从部分简单方法开始把 `ctx.validate` 改成 `ctx.tValidate` | ||
1. 可以解决 ts 项目中参数校验代码写两遍类型的问题,提升代码重用率,可维护性等问题 | ||
2. 用标准 json-schema 来做参数校验,是更加标准的业界做法,内置更多业界标准模型 | ||
@@ -320,4 +325,8 @@ ## API | ||
## 怎么写 typebox 定义 | ||
参考 [https://github.com/sinclairzx81/typebox#types](https://github.com/sinclairzx81/typebox#types) | ||
## License | ||
[MIT](LICENSE) |
15050
322
48