Mundarija (25)
- Bu darsda
- 1. Nega bu kerak?
- 2. Bitta sxema, to'rt kutubxona
- 2.1 Vazifa
- 2.2 Zod (eslatma)
- 2.3 Joi 18
- 2.4 class-validator 0.15
- 2.5 express-validator 7
- 2.6 Yup — qisqacha
- 3. O'lchov: tezlik, import va hajm
- 3.1 Kanon natijalari
- 3.2 Raqamlarni to'g'ri o'qish
- 4. Standard Schema: middleware kutubxonaga bog'lanmasin
- 4.1 G'oya
- 5. Qaysi birini tanlash
- 6. API qadami o'rniga: kanon tajribasi va nega kirmadi
- 7. Ko'p uchraydigan xatolar
- 8. Mashqlar
- 1-mashq (oson): qaysi kutubxona?
- 2-mashq (o'rta): Joi xatolarini Problem Details'ga
- 3-mashq (qiyin): kichik "Standard Schema" validator
- 4-mashq: kanon tajribasini takrorlang (ixtiyoriy)
- 9. Real ishda
- Xulosa
- Manbalar
Backend validatorlari: Joi, class-validator va express-validator — Zod bilan o'lchab taqqoslash
Qisqacha: Zod yagona validator emas. Joi — eng eski va yetuk (hapi'dan), zanjirli API bilan.
abortEarly: falsebilan u hamma xatoni beradi. Lekin TypeScript turini o'zi chiqarmaydi. class-validator — klass va dekoratorlar (@IsString()), NestJS'ning sukut tanlovi; build vareflect-metadatatalab qiladi. express-validator — Express middleware zanjiri (body("matn").isLength(...)),requstida asinxron ishlaydi va ortiqcha maydonni o'zi tekshirmaydi. Bir xil sxemadagi kanon o'lchovida Zod eng tez chiqdi (6.63 mln/s), Joi — 0.84, class-validator — 0.30. Kanon ularni o'rnatmadi; mavjud loyihada uchratasiz — o'qiy olish va ko'chira olish kerak. Kutubxonalarni almashtirishni Standard Schema osonlashtiradi.
Bu darsda
- Bitta sxemani Joi, class-validator va express-validator'da yoza olasiz.
- Ularning xato matnlari, sukut xatti-harakati va tuzoqlarini (tur aylantirish, ortiqcha maydon) bilasiz.
- Tezlik, import vaqti va hajmni kanon o'lchovi bo'yicha taqqoslaysiz.
- Standard Schema orqali middleware'ni kutubxonaga bog'liq bo'lmagan qilasiz.
- Yangi loyiha uchun validator tanlashni asoslay olasiz.
Oldin bilishingiz kerak: Zod 4 serverda, Validatsiya: nima uchun, qayerda va qanday, Validatsiya va forma kutubxonalari muqobillari, Legacy dekoratorlar va reflect-metadata.
1. Nega bu kerak?
vazifalar-api da Zod bor va u yetarli. Lekin ishga kirgan birinchi kuningizda sizni 2019-yilda yozilgan Express loyihasi kutishi mumkin — unda Joi yoki express-validator bo'ladi. NestJS loyihasida esa deyarli doim class-validator. Ularni o'qiy olmasangiz, kodni o'zgartirish qo'rqinchli bo'ladi.
Ikkinchi sabab — tanlov. "Hamma Zod ishlatadi" — dalil emas. Har kutubxonaning o'z narxi bor: paket hajmi, ishga tushish vaqti, tezlik, TypeScript bilan qulaylik. Bu narxni taxmin bilan emas, o'lchov bilan bilish kerak.
O'xshatish: turli shaharlarning yo'l harakati belgilari. Ma'nosi bir xil ("to'xta", "tezlik 60"), lekin shakli boshqa. Tajribali haydovchi boshqa shaharga borsa ham ularni taniydi. Validatorlar ham shunday: g'oya bir — shakl tekshiruvi, xatolar ro'yxati, tozalangan qiymat; sintaksis turlicha.
Frontend qismida Valibot, ArkType va Standard Schema'ni ko'rgansiz. Bu dars — backend'da ko'p uchraydigan uchtasi haqida.
2. Bitta sxema, to'rt kutubxona
2.1 Vazifa
Kanon tajribasi (t30) hamma kutubxonada bir xil qoidani yozdi:
matn— satr,trim, 1–200 belgi;bajarildi— ixtiyoriy, faqat haqiqiytrue/false;- ortiqcha maydon — taqiqlangan.
Yaroqsiz kirish: { "matn": "", "bajarildi": "ha", "ortiqcha": 1 } — uchala qoida buzilgan.
Eslatma: bu bo'limdagi Joi, class-validator va express-validator bloklari kurs tekshiruvchisida ishga tushmaydi (paketlar o'rnatilmagan) — chiqishlar kanon tajribasi fayllaridan olingan (Node 24.21.0, Windows 11, 2026-10-24).
2.2 Zod (eslatma)
import { z } from "zod";
const Zod = z.strictObject({
matn: z.string().trim().min(1).max(200),
bajarildi: z.boolean().optional(),
});
Zod.safeParse(yaroqsiz);matn: Too small: expected string to have >=1 characters
bajarildi: Invalid input: expected boolean, received string
(ildiz): Unrecognized key: "ortiqcha"2.3 Joi 18
Joi — hapi freymvorkidan chiqqan, 2012-yildan beri rivojlanib kelayotgan kutubxona. Zanjirli API Zod'ga o'xshaydi:
import Joi from "joi"; // 18.3.0
const JoiS = Joi.object({
matn: Joi.string().trim().min(1).max(200).required(),
bajarildi: Joi.boolean().strict(),
});
const { error, value } = JoiS.validate(yaroqsiz, {
abortEarly: false,
});
console.log(error.details.map((d) => d.message).join(" | "));"matn" is not allowed to be empty | "bajarildi" must be a boolean | "ortiqcha" is not allowedTo'rtta farq:
- Maydonlar sukut bo'yicha ixtiyoriy. Zod'da teskari: majburiy, ixtiyoriylari
.optional(). Joi'da majburiy maydon —.required(). Esdan chiqsa —matnsiz so'rov jim o'tadi. - Birinchi xatoda to'xtaydi. Hamma xato kerak bo'lsa —
{ abortEarly: false }. - Turlarni o'zi aylantiradi.
Joi.boolean()sukut bo'yicha"true"satrini ham qabul qiladi vatruega aylantiradi (convert: true). Query uchun qulay, tana uchun xavfli. Kanon tajribasi.strict()qo'shgan. - TypeScript turi yo'q.
value—any. Tur qo'lda yoziladi va sxema bilan ajralib ketishi mumkin.
Ortiqcha maydon sukut bo'yicha rad etiladi ("ortiqcha" is not allowed) — Zod'ning strictObject iga o'xshash. { stripUnknown: true } bilan jim olib tashlanadi.
2.4 class-validator 0.15
class-validator — qoidalar klass maydonlari ustidagi dekoratorlar bilan yoziladi. Legacy dekoratorlar darsida ko'rgan @ sintaksis:
import "reflect-metadata"; // 0.2.2
import { IsBoolean, IsOptional, IsString, Length, validateSync }
from "class-validator"; // 0.15.1
import { plainToInstance, Transform }
from "class-transformer"; // 0.5.1
class YangiVazifaDto {
@IsString()
@Length(1, 200)
@Transform(({ value }) =>
typeof value === "string" ? value.trim() : value)
matn!: string;
@IsOptional()
@IsBoolean()
bajarildi?: boolean;
}
const dto = plainToInstance(YangiVazifaDto, yaroqsiz);
const xatolar = validateSync(dto, {
whitelist: true,
forbidNonWhitelisted: true,
});property ortiqcha should not exist | matn must be longer than or equal to 1 characters | bajarildi must be a boolean valueIshlash tartibi ikki qadam:
plainToInstance(class-transformer) — oddiy JSON obyektini klass nusxasiga aylantiradi va@Transformlarni bajaradi.validateSync— dekoratorlardagi qoidalarni tekshiradi.
whitelist: true — dekoratorsiz maydonlarni olib tashlaydi; forbidNonWhitelisted: true — ularni xato qiladi. Ikkalasi ham sukut bo'yicha o'chiq — esdan chiqsa, mass assignment eshigi ochiq (injeksiya va mass assignment).
Muhim cheklov — build kerak. Node 24 ning type stripping'i dekoratorlarni bajarmaydi (TS'ni Node'da to'g'ridan); emitDecoratorMetadata esa tsc kompilyatsiyasini talab qiladi. Kanon tajribasida dekoratorlar oddiy funksiya sifatida qo'lda chaqirilgan (IsString()(YangiVazifaDto.prototype, "matn")) — faqat o'lchash uchun. NestJS (30-qism) aynan shu kutubxonani ishlatadi va build bilan keladi.
2.5 express-validator 7
express-validator — validator emas, aniqrog'i Express middleware zanjiri. U validator.js kutubxonasi ustida qurilgan va to'g'ridan-to'g'ri req ni tekshiradi:
import { body, checkExact, validationResult }
from "express-validator"; // 7.3.2
app.post(
"/vazifalar",
body("matn").isString().trim().isLength({ min: 1, max: 200 }),
body("bajarildi").optional().isBoolean({ strict: true }),
checkExact(), // ortiqcha maydonlar uchun — alohida!
(req, res) => {
const natija = validationResult(req);
if (!natija.isEmpty()) {
return res.status(422).json({ xatolar: natija.array() });
}
// req.body.matn — endi trim qilingan, lekin turi baribir any
},
);Kanon tajribasi (checkExact siz):
matn: Invalid value | bajarildi: Invalid value (ortiqcha maydon — tekshirilmadi: alohida checkExact() kerak)Uch narsaga e'tibor:
- Xabar — "Invalid value". Har qoidaga
.withMessage("…")yozmasangiz, mijoz nima noto'g'ri ekanini bilmaydi. - Ortiqcha maydon jim o'tadi —
checkExact()alohida qo'shilmasa. reqni o'zgartiradi —trim()req.body.matnni joyida o'zgartiradi. Express 5 dareq.queryga yozib bo'lmaydi (req obyekti) — query sanitizatsiyasi bilan ehtiyot bo'ling. TS turi —any.
Afzalligi: Express'ga tabiiy, sxema yozish shart emas, validator.js ning yuzlab tayyor tekshiruvlari (isEmail, isIBAN, isMobilePhone("uz-UZ")) bor.
2.6 Yup — qisqacha
Yup — Formik bilan mashhur bo'lgan frontend validatori; serverda ham ishlaydi. API Zod'ga yaqin (yup.object({ matn: yup.string().required() })), InferType bilan tur chiqaradi, lekin sukut bo'yicha asinxron va turlarni aylantiradi ("5" → 5). Kanonda o'lchanmagan. Yangi loyihada Yup tanlashga sabab kam — eski React formalarida uchratasiz.
Tekshirib ko'ring: Uch kutubxonadan qaysi birida ortiqcha maydon sukut bo'yicha xato, qaysi birida jim o'tadi?
Javob
Joi — sukut bo'yicha xato ("ortiqcha" is not allowed). class-validator — jim o'tadi; whitelist + forbidNonWhitelisted yoqilishi kerak. express-validator — jim o'tadi; checkExact() kerak. Zod'da z.object jim olib tashlaydi, z.strictObject xato beradi. Sukut qiymatni bilmaslik — mass assignment xatolarining asosiy sababi.
3. O'lchov: tezlik, import va hajm
3.1 Kanon natijalari
Kanon (t30): import — alohida jarayonda, 9 marta, mediana; tezlik — 200 000 yaroqli va 20 000 yaroqsiz tekshiruv; hajm — alohida papkada npm i. Node 24.21.0, i5-12500H, band mashina, bitta o'lchov:
- zod 4.6.76,63 mln/s
- zod/mini2,69 mln/s
- joi 18.3.00,84 mln/s
- class-validator 0.15.10,3 mln/s
- express-validator 7.3.2async, req obyektida0,009 mln/s
Manba: kanon t30-validatorlar, Node 24.21.0, i5-12500H, 2026-10-24
| Kutubxona | Paketlar / hajm | Import | Yaroqsiz, mln/s |
|---|---|---|---|
| zod 4.6.7 | 1 / 5.9 MB | 99.9 ms | 0.425 |
| joi 18.3.0 | 8 / 2.2 MB | 84.8 ms | 0.293 |
| class-validator + class-transformer + reflect-metadata | 6 / 16.7 MB | 203 ms | 0.113 |
| express-validator 7.3.2 | 3 / 2.3 MB | 108.3 ms | — |
3.2 Raqamlarni to'g'ri o'qish
- Tezlik farqi katta, lekin ahamiyati kichik. Joi ham sekundiga 840 000 ta tekshiruv qiladi. API'da bitta so'rov uchun tekshiruv mikrosekundlar oladi; DB so'rovi esa millisekundlar. Kanon o'lchovida Problem Details yasash ham sezilmagan edi. Tezlik — hal qiluvchi emas, faqat bitta omil.
- express-validator raqami boshqa narsani o'lchaydi. U
reqga o'xshash obyekt ustida, asinxron, har qoida alohida middleware sifatida ishlaydi — 20 000 marta. To'g'ridan solishtirib bo'lmaydi; faqat "eng og'ir yo'l" deb tushuning. - Import vaqti — server bir marta ishga tushadi, 100 ms farq odatda muhim emas. Serverless'da (har so'rovga sovuq start) esa muhim.
- class-validator — eng og'ir: 16.7 MB va 203 ms. Sabab — uchta paket va ularning bog'liqliklari: class-validator o'zi
validatorva telefon raqamlari kutubxonasilibphonenumber-jsga bog'liq. npm ma'lumotiga ko'ra (2026-10),libphonenumber-jsning o'zi ochilgan holda ~10 MB. - Yaroqsiz qiymat hamma joyda sekinroq — xato obyektlarini yasash qimmat. Hujumchi ataylab yaroqsiz so'rovlar yuborsa, aynan shu yo'l ishlaydi.
Tekshirib ko'ring: API sekundiga 2 000 so'rov oladi. Joi'dan Zod'ga o'tish server CPU'sining qancha qismini tejaydi?
Javob
Joi: 2 000 / 840 000 ≈ 0.24 % bitta yadro vaqti; Zod: 2 000 / 6 630 000 ≈ 0.03 %. Tejash — yadroning ~0.2 % i. Amalda sezilmaydi. Kutubxonani tezlik uchun almashtirish arzimaydi; turlar, xato sifati va jamoa tajribasi muhimroq.
4. Standard Schema: middleware kutubxonaga bog'lanmasin
4.1 G'oya
Frontend qismida Standard Schema ni ko'rgansiz: Zod, Valibot, ArkType va boshqalar bitta umumiy interfeysni qo'llaydi — har sxemada ~standard.validate(value) bor. Natija: { value } yoki { issues: [{ message, path }] }.
Serverda bu nima beradi? tekshir() middleware'ini Zod'ga emas, Standard Schema'ga yozsangiz — u istalgan mos kutubxona bilan ishlaydi. Kutubxona almashtirilsa, middleware o'zgarmaydi. Blok Node'da Zod 4 va Valibot 1.5 bilan tekshiriladi:
import type { StandardSchemaV1 } from "@standard-schema/spec";
import { z } from "zod";
import * as v from "valibot";
type FieldError = { joy: string; xabar: string };
type Result<T> =
| { ok: true; value: T }
| { ok: false; errors: FieldError[] };
async function check<S extends StandardSchemaV1>(
schema: S, value: unknown, place: string,
): Promise<Result<StandardSchemaV1.InferOutput<S>>> {
const r = await schema["~standard"].validate(value);
if (r.issues === undefined) return { ok: true, value: r.value };
const errors = r.issues.map((i) => {
const keys = (i.path ?? []).map((p) =>
typeof p === "object" ? String(p.key) : String(p));
return { joy: [place, ...keys].join("."), xabar: i.message };
});
return { ok: false, errors };
}
const ZodTask = z.strictObject({
matn: z.string().trim().min(1, { error: "matn bo'sh" }),
bajarildi: z.boolean().optional(),
});
const ValibotTask = v.strictObject({
matn: v.pipe(v.string(), v.trim(), v.minLength(1, "matn bo'sh")),
bajarildi: v.optional(v.boolean()),
});
const bad = { matn: " ", bajarildi: "ha" };
for (const schema of [ZodTask, ValibotTask]) {
console.log(schema["~standard"].vendor);
console.log(await check(schema, { matn: " Non " }, "body"));
const r = await check(schema, bad, "body");
if (!r.ok) {
for (const e of r.errors) console.log(` ${e.joy} | ${e.xabar}`);
}
}Konsolda:
zod
{ ok: true, value: { matn: 'Non' } }
body.matn | matn bo'sh
body.bajarildi | Invalid input: expected boolean, received string
valibot
{ ok: true, value: { matn: 'Non' } }
body.matn | matn bo'sh
body.bajarildi | Invalid type: Expected boolean but received "ha"Bitta check funksiyasi — ikki kutubxona. Natija turi ham to'g'ri chiqadi: StandardSchemaV1.InferOutput<S>. Farq faqat sukut xabarlarida.
Uch nozik joy:
validatePromise qaytarishi mumkin (async tekshiruvlar uchun) — shuning uchunawait.pathelementi kalit ("matn") yoki obyekt ({ key: "matn" }) bo'lishi mumkin — ikkalasi ham normallashtiriladi.- Joi 18 Standard Schema'ni qo'llaydi: uning bog'liqliklarida
@standard-schema/specbor. Biz Joi 18.3.0 da tekshirdik (Node 24.21.0):Joi.object(...)["~standard"].vendor—"joi",validate({ matn: "" })esa{ issues: [{ message: '"matn" is not allowed to be empty', path: ["matn"] }] }qaytardi. Demak yuqoridagicheckJoi sxemasi bilan ham ishlaydi. - class-validator va express-validator Standard Schema'ni qo'llamaydi (npm'dagi bog'liqliklariga ko'ra, 2026-10 holatida) — ular uchun adapter qo'lda yoziladi.
5. Qaysi birini tanlash
| Vaziyat | Tanlov | Nega |
|---|---|---|
| yangi Express/Fastify/Hono loyiha, TypeScript | Zod (yoki Valibot) | sxemadan tur, toJSONSchema, Standard Schema, eng keng ekotizim |
| NestJS | class-validator (sukut) yoki Zod pipe | NestJS hujjati va DTO'lar class-validator atrofida; Zod ham qo'llanadi (NS-19) |
| eski Express loyiha, express-validator bor | qoldiring, checkExact() va xabarlarni tekshiring |
qayta yozish xavfli; asta-sekin yangi marshrutlarda Zod |
| JS loyiha (TS'siz), hapi | Joi | yetuk, hujjati boy; tur kerak emas |
| brauzer bundle'i muhim | Valibot yoki zod/mini |
kichik hajm (RE-35) |
Asosiy qoida: bitta loyihada bitta validator. Ikki kutubxona — ikki xil xato formati, ikki xil sukut, ikki marta o'rganish.
6. API qadami o'rniga: kanon tajribasi va nega kirmadi
Bu dars uchun vazifalar-api da holat yo'q — loyiha o'zgarmaydi. Kanon tajribasi va qarori:
- O'lchandi: Joi 18.3.0, class-validator 0.15.1 (+ class-transformer 0.5.1, reflect-metadata 0.2.2), express-validator 7.3.2 — alohida papkada, loyihaga kirmadi (
t30-validatorlar). - Qaror — Zod qoladi: loyiha TypeScript, build yo'q (type stripping) — class-validator dekoratorlari ishlamaydi; sxemadan tur va JSON Schema kerak; frontend (22-qism) ham Zod ishlatadi — bir xil fikrlash.
- Valibot va ArkType o'rnatilmadi (versiyalar ro'yxatda: valibot 1.5.0, arktype 2.2.8). Standard Schema adapteri esa yuqoridagi blokda ishlaydi — kerak bo'lsa, almashtirish arzon.
Sizning qadamingiz — mashqlarda: kanon sxemasini Joi'ga ko'chirib, xatti-harakat farqlarini o'zingiz ko'rasiz.
7. Ko'p uchraydigan xatolar
1. Joi'da .required() ni unutish. Joi'da hamma maydon sukut bo'yicha ixtiyoriy.
2. Joi convert tuzog'i. Joi.boolean() "true" satrini true qiladi, Joi.number() — "5" ni 5. Tana uchun .strict() yoki { convert: false }.
3. class-validator'da whitelist siz. Ortiqcha maydonlar DTO'ga o'tadi va keyin ORM'ga tushishi mumkin.
4. class-validator'da plainToInstance ni o'tkazib yuborish. Oddiy obyektga validateSync — dekoratorlar topilmaydi, tekshiruv jim o'tadi.
5. express-validator'da validationResult ni tekshirmaslik. Zanjir xatolarni yig'adi, lekin so'rovni o'zi to'xtatmaydi — handler'da isEmpty() shart.
6. "Invalid value" xabarlari. .withMessage() siz mijoz nima noto'g'ri ekanini bilmaydi.
7. Bir loyihada ikki validator. Xato formati va sukut qoidalari ikkiga bo'linadi.
8. Mashqlar
Yechimlar kurs/mashqlar/25/31-validatorlar/ da.
1-mashq (oson): qaysi kutubxona?
- Dekoratorlar bilan yoziladi —
requstida middleware zanjiri —- Maydonlar sukut bo'yicha ixtiyoriy,
.required()kerak — - Ortiqcha maydon uchun
checkExact()— - Kanon o'lchovida eng og'ir paket (MB) —
Yechim
- class-validator —
@IsString(),@Length(). - express-validator —
body("matn").isLength(...). - Joi —
Joi.string().required(). - express-validator — sukut bo'yicha ortiqcha maydon jim o'tadi.
- class-validator — 16.7 MB (uch paket va ularning bog'liqliklari — jami 6 paket).
2-mashq (o'rta): Joi xatolarini Problem Details'ga
Joi error.details massivi shunday ko'rinadi: [{ message, path: ["matn"], type: "string.empty" }, …]. joiToErrors(details, place) yozing — u [{ joy, xabar }] qaytarsin; xabardagi qo'shtirnoqli maydon nomini ("matn" ) olib tashlab, kichik harf bilan boshlasin. Kanon tajribasidagi uchta xato bilan sinang. Bu toza JS — «Ishga tushir» bilan ishlaydi.
Yechim
function joiToErrors(details, place) {
return details.map((d) => {
const text = d.message.replace(/^"[^"]*"\s*/, "");
return {
joy: [place, ...d.path].join("."),
xabar: text.charAt(0).toLowerCase() + text.slice(1),
};
});
}
const details = [
{ message: '"matn" is not allowed to be empty', path: ["matn"] },
{ message: '"bajarildi" must be a boolean', path: ["bajarildi"] },
{ message: '"ortiqcha" is not allowed', path: ["ortiqcha"] },
];
for (const e of joiToErrors(details, "body")) {
console.log(`${e.joy} | ${e.xabar}`);
}Konsolda:
body.matn | is not allowed to be empty
body.bajarildi | must be a boolean
body.ortiqcha | is not allowedHaqiqiy loyihada Joi'ga messages: { "string.empty": "…" } bilan o'zbekcha xabarlar beriladi — type maydoni (string.empty) kalit bo'ladi.
3-mashq (qiyin): kichik "Standard Schema" validator
Kutubxonasiz o'z validatoringizni yozing: objectSchema(shape) — shape — { kalit: (qiymat) => xabar | null }. Qaytgan obyektda ~standard bo'lsin: { version: 1, vendor: "ilmhamroh", validate(value) }. validate — obyekt bo'lmasa bitta xato; har maydon tekshiriladi; shape da yo'q kalit — "noma'lum kalit". Natija Standard Schema shaklida ({ value } yoki { issues: [{ message, path }] }). Uni darsdagi check g'oyasidagi oddiy funksiya bilan sinang.
Yechim
function objectSchema(shape) {
return {
"~standard": {
version: 1,
vendor: "ilmhamroh",
validate(value) {
if (typeof value !== "object" || value === null) {
const issue = { message: "obyekt kutilgan", path: [] };
return { issues: [issue] };
}
const issues = [];
for (const [key, rule] of Object.entries(shape)) {
const message = rule(value[key]);
if (message) issues.push({ message, path: [key] });
}
for (const key of Object.keys(value)) {
if (!(key in shape)) {
const message = `noma'lum kalit: ${key}`;
issues.push({ message, path: [] });
}
}
return issues.length ? { issues } : { value };
},
},
};
}
const Task = objectSchema({
matn: (x) => typeof x === "string" && x.trim().length > 0
? null : "matn bo'sh",
bajarildi: (x) => x === undefined || typeof x === "boolean"
? null : "bajarildi — true/false",
});
async function check(schema, value) {
const r = await schema["~standard"].validate(value);
if (!r.issues) return "OK";
return r.issues
.map((i) => `${i.path.join(".") || "(ildiz)"}: ${i.message}`)
.join("; ");
}
console.log(await check(Task, { matn: "Non" }));
const bad = { matn: " ", bajarildi: "ha", rol: 1 };
console.log(await check(Task, bad));
console.log(await check(Task, null));Konsolda:
OK
matn: matn bo'sh; bajarildi: bajarildi — true/false; (ildiz): noma'lum kalit: rol
(ildiz): obyekt kutilgan20 qatorlik kod — va u darsdagi Standard Schema middleware'i bilan ishlaydi. Standard Schema "kutubxona" emas, kelishuv ekani shunda ko'rinadi.
4-mashq: kanon tajribasini takrorlang (ixtiyoriy)
Loyihadan tashqaridagi alohida papkada (npm init -y, keyin npm i --save-exact joi@18.3.0) YangiVazifaSxemasi ning Joi variantini yozing. Uchta holatni sinang: {"matn":"","bajarildi":"ha","ortiqcha":1}, {"bajarildi":"true"} (.strict() bilan va siz), {"matn":" Non "}. Natijalarni Zod bilan solishtiring va farqlarni ro'yxat qiling. vazifalar-api ga hech narsa qo'shmang.
9. Real ishda
- NestJS loyihalarining ko'pchiligi — class-validator DTO'lari:
@Body() dto: CreateTaskDtova globalValidationPipe({ whitelist: true, forbidNonWhitelisted: true }). Bu sozlamalar — intervyuda ko'p so'raladi (30-qism). - hapi va eski Express loyihalari — Joi;
celebratepaketi Joi'ni Express middleware'iga aylantiradi. - O'zbekistondagi ko'p loyihalarda (2018–2022 yillarda yozilgan) express-validator uchraydi — uni Zod'ga bosqichma-bosqich ko'chirish odatiy vazifa.
- Fastify JSON Schema'ni (Ajv) to'g'ridan-to'g'ri ishlatadi — eng tez yo'llardan biri; Zod'dan
toJSONSchemabilan unga o'tish mumkin (Zod 4 serverda).
Xulosa
- Joi — yetuk, zanjirli, turni chiqarmaydi; maydonlar sukut bo'yicha ixtiyoriy,
abortEarlyvaconvertga e'tibor. - class-validator — dekoratorlar, NestJS standarti; build,
reflect-metadata,whitelist+forbidNonWhitelistedshart. - express-validator —
requstida middleware zanjiri;checkExact(),withMessage(),validationResultni unutmang. - Kanon o'lchovi: Zod 6.63, Joi 0.84, class-validator 0.30 mln/s — farq katta, lekin API'da hal qiluvchi emas.
- Standard Schema bilan middleware kutubxonadan mustaqil bo'ladi; bitta loyihada — bitta validator.
Keyingi dars: Xato turlari va custom error iyerarxiyasi — HttpXato o'rniga IlovaXatosi, ValidatsiyaXatosi, TopilmadiXatosi iyerarxiyasi va operatsion xato bilan dasturchi xatosini ajratish.
Manbalar
- Joi API — joi.dev/api (
abortEarly,convert,stripUnknown) - class-validator — github.com/typestack/class-validator (
whitelist,forbidNonWhitelisted) - express-validator — express-validator.github.io/docs (
checkExact,validationResult) - Standard Schema — standardschema.dev,
@standard-schema/spec1.1.0; Joi 18 bog'liqligi — npmjs.com/package/joi (18.3.0, 2026-10-16) - class-validator 0.15.1 bog'liqliklari (
validator,libphonenumber-js) — npmjs.com/package/class-validator - Valibot — valibot.dev
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!