日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用class-validator替换Joi包的方法

發布時間:2025/3/8 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用class-validator替换Joi包的方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

對每個接口的傳入參數進行校驗,是一個Web后端項目的必備功能,有一個npm包叫Joi可以很優雅的完成這個工作,比如這樣子:

const schema = {userId: Joi.string() }; const {error, value} = Joi.validate({ userId: 'a string' }, schema); 復制代碼

我們使用Typescript是希望得到明確的類型定義,減少出錯的可能性。在一個后端項目中,給每個接口定義它的傳入參數結構以及返回結果的結構,是一件很值得做的事情,因為這樣給后續的維護帶來極大的便利。比如這樣子:

export type IFooParam = {userId: string }export type IFooResponse = {name: string }async foo (param: IFooParam): Promise<IFooResponse> {// Your business codereturn {name: 'bar'} } 復制代碼

現在問題就來了,如果傳入參數希望加多一個字段,我們必須得修改2個地方,一個是Joi的校驗,一個是IFooParam類型的定義。有沒有好的辦法解決這個問題呢?

Class-validaotr

有一個npm包叫class-validator, 是采用注解的方式進行校驗,底層使用的是老牌的校驗包validator.js。
這次試用,發現通過一些小包裝,居然做到像Joi一樣優雅的寫法,而且更好用!

定義傳入/返回結構

import {Length, Min, Max} from 'class-validator'export class IRegister {@Length(11)phone: string@Length(2, 10)name: string@Min(18)@Max(50)age: number }class Button {text: string }export class ORegister {/*** user's id*/userId: stringbuttons: Button[] } 復制代碼

這里定義了2個類,IRegister為傳入參數,通過class-validator規定的注解方式做校驗,ORegister為返回結果。

class-validator官方提供的方式還不能直接對一個請求的body進行校驗,它要求必須要是IRegister類的一個對象,所以需要做一些處理。

使用class-transformer做轉化

跟class-validator的作者也開源了另外一個包,叫class-transformer, 可以將一個json轉成指定的類的對象,官方的例子是這樣的:

import {plainToClass} from "class-transformer";let users = plainToClass(User, userJson); // to convert user plain object a single user. also supports arrays 復制代碼

利用這一點,我們寫一個小工具:

import * as classTransformer from 'class-transformer' import {validate} from 'class-validator' import * as lodash from 'lodash'export class ValidateUtil {private static instance: ValidateUtilprivate constructor () {}static getInstance () {return this.instance || (this.instance = new ValidateUtil())}async validate (Clazz, data): Promise<any> {const obj = classTransformer.plainToClass(Clazz, data)const errors = await validate(obj)if (errors.length > 0) {console.info(errors)throw new Error(lodash.values(errors[0].constraints)[0])}return obj} } 復制代碼

這個小工具提供了一個validate方法,第一個參數是一個類定義,第二個是一個json,它先利用class-transformer將json轉成指定類的對象,然后使用class-validator做校驗,如果校驗錯誤將拋出錯誤,否則返回轉化后的對象。

在Controller中使用

有了上面的工具,就可以方便地在代碼中對傳入參數做校驗了,比如這樣:

static async register(ctx) {const iRegister = await ValidateUtil.getInstance().validate(IRegister, ctx.request.body)const oRegister = await UserService.register(iRegister)ctx.body = oRegister} 復制代碼

新問題

到了這里,完美地使用class-validator替換掉了Joi。

但是還有一個問題沒解決,也是之前一直遺留的問題。

我們使用apidoc編寫接口文檔,當新增或修改一個接口時,是通過編寫一段注釋,讓apidoc自動生成html文檔,將文檔地址發給前端,可以減少雙方的頻繁溝通,而且對前端的體驗也是非常好的。比如寫這樣一段注釋:

/*** @api {post} /user/registerOld registerOld* @apiGroup user* @apiName registerOld* @apiParam {String} name user's name* @apiParam {Number} age user's age* @apiSuccess {String} userId user's id */router.post('/user/registerOld', UserController.register) 復制代碼

apidoc會幫我們生成這樣的文檔:

問題比較明顯,當我們要新增一個參數時,需要修改一次類的定義,同時還要修改一次apidoc的注釋,很煩,由于很煩,文檔會慢慢變得沒人維護,新同事就會吐槽沒有文檔或者文檔太舊了。

理想的情況是代碼即文檔,只需要修改類的定義,apidoc文檔自動更新。

探索apidoc根據class-validator的定義生成

從同事的分享中得知一個廢棄的npm包,叫apidoc-plugin-ts, 可以實現根據ts的interface定義來生成apidoc的。官方的例子:

filename: ./employers.tsexport interface Employer {/*** Employer job title*/jobTitle: string;/*** Employer personal details*/personalDetails: {name: string;age: number;} }@apiInterface (./employers.ts) {Person} 復制代碼

會轉化成:

@apiSuccess {String} jobTitle Job title@apiSuccess {Object} personalDetails Empoyer personal details@apiSuccess {String} personalDetails.name@apiSuccess {Number} personalDetails.age 復制代碼

雖然不知道為什么作者要廢棄它,但是它的思想很好,源碼也很有幫助。

給我的啟發是,參考這個npm包,寫一個針對class定義來生成apidoc的插件就行了。

造輪子: apidoc-plugin-class-validator

輪子的制造細節不適合在這里陳述,基本上參考apidoc-plugin-ts,目前已經發布在npm上了,apidoc-plugin-class-validator

使用apidoc-plugin-class-validator

以上面的注冊接口為例,使用方法:

/*** @api {post} /user/register register* @apiGroup user* @apiName register* @apiParamClass (src/user/io/Register.ts) {IRegister}* @apiSuccessClass (src/user/io/Register.ts) {ORegister}*/router.post('/user/register', UserController.register) 復制代碼

就會生成文檔:

后續新增字段,只需修改IRegister類的定義就行,真正做到了修改一處,處處生效,代碼即文檔的效果。

本文的demo代碼在這里,這是一個簡單的web后端項目,看代碼更容易理解。

轉載于:https://juejin.im/post/5c9b3b53f265da612e6d708c

總結

以上是生活随笔為你收集整理的使用class-validator替换Joi包的方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲品质自拍视频网站 | 黄色成年人网站 | 欧美 丝袜 自拍 制服 另类 | 丰满少妇一级 | 熟女肥臀白浆大屁股一区二区 | 国产精品女同 | 一区二区三区资源 | 天天夜夜操 | 欧美日韩国产二区 | 国产中文字幕一区二区三区 | 男男车车的车车网站w98免费 | 欧美极品一区二区三区 | 国产一区二区在线看 | 一个人在线观看免费视频www | 一区二区三区黄色 | 日本福利一区 | 在线观看免费黄网站 | 欧美日韩国产免费一区二区三区 | 久91| 激情总合网 | 欧美性免费 | 亚洲一区二区精华 | 成人免费毛片男人用品 | 噜噜噜噜噜色 | 天堂va蜜桃一区 | 粉嫩av网址 | 成人在线观看免费爱爱 | 精品国产一二三区 | 2024av视频| 日本一区二区成人 | 国产精品第 | 牛av| 色久在线 | 人妻换人妻a片爽麻豆 | www.欧美国产| 精品乱码一区二区三四区视频 | 成人资源站 | 18视频在线观看男男 | 欧美jizz欧美性大全 | 校园春色综合网 | 日本少妇高潮喷水xxxxxxx | 午夜一二区 | 五月情婷婷| 激情五月综合网 | 成年人免费网站 | 一级黄色在线播放 | 黄色欧美在线 | 欧美在线91 | 国产传媒专区 | 最新精品国产 | 东北女人av | 91日本在线观看 | 日韩一区免费 | 97国产成人无码精品久久久 | 亚洲a∨无码无在线观看 | 国产欧美精品一区二区 | 公侵犯人妻中文字慕一区二区 | 九九热九九爱 | 九色自拍 | 女女调教被c哭捆绑喷水百合 | h视频在线看 | 午夜精品福利一区二区三区蜜桃 | caopeng在线 | 色屁屁ts人妖系列二区 | 欧美综合视频在线 | 国产人妻精品午夜福利免费 | 日韩色黄大片 | 久久精品国产一区 | 欧美黑人添添高潮a片www | 国产真实老熟女无套内射 | 一区二区三区日韩 | 精品久久成人 | 精品欧美一区二区三区成人 | xx在线视频 | 美女网站免费观看视频 | 免费看黄视频的网站 | 成年人黄国产 | 性xxxx欧美老肥妇牲乱 | 性毛片| 欧美二区三区 | 18成人在线| 干爹你真棒插曲mv在线观看 | 依依成人在线视频 | 超碰天天 | 无套日出白浆 | 日韩精品一区二区三 | 亚洲成人xxx| 激情视频一区 | 欧美黑吊大战白妞欧美大片 | 色妺妺视频网 | 国产女人精品视频 | 成人免费黄色大片 | 理论片第一页 | 男人天堂视频在线 | 天天干天天爽天天操 | 精品国产自在精品国产精小说 | www.人人干| 美女131爽爽爽做爰视频 | 亚洲av永久无码精品一区二区国产 |