5.9-bob: Validatsiya — express-validator, Joi, Zod, class-validator
5-QISM — Node.js Backend · 9-mavzu
1. Kirish va motivatsiya
Backend dasturlashning eng muhim qoidasi: "Hech qachon foydalanuvchiga ishonma" (Never trust the client — 14). Foydalanuvchi (yoki hacker) so'rovga istalgan narsa yuborishi mumkin: bo'sh maydon, noto'g'ri format, juda uzun matn, zararli kod (SQL injection, XSS — 14), kutilmagan tur. Validatsiya — bu ma'lumotni ishlatishdan oldin tekshirish: backend'ning birinchi himoya chizig'i.
5.6-bobda body'ni qabul qilishni (req.body), 5.7-bobda 400/422 status (xato so'rov) ni ko'rdik. 5.8-bobda Zod bilan env'ni tekshirgandik. Endi validatsiyani to'liq, professional darajada o'rganamiz: nimani, qayerda, qanday tekshirish; va to'rt asosiy vosita — Zod (zamonaviy, TypeScript-first), Joi (kuchli, klassik), express-validator (Express'ga xos), class-validator (dekorator, NestJS — 8).
O'xshatish: validatsiya — klubning eshik qorovuli (face control). Hech kim ichkariga tekshiruvsiz kirolmaydi: yoshi, kiyimi, taklifnomasi tekshiriladi. Noto'g'ri bo'lsa — eshikda to'xtatiladi (400 — 5.7), ichkariga (biznes logika, DB) o'tkazilmaydi. Qorovulsiz klub — har xil bezori ichkariga kiradi (xavfsizlik falokati — 14).
Nega muhim?
- Xavfsizlik (14) — noto'g'ri/zararli ma'lumotni darvozada to'xtatish (SQL injection, NoSQL injection, XSS).
- Ma'lumot yaxlitligi — DB'ga (6) faqat to'g'ri shakldagi ma'lumot.
- Yaxshi UX — aniq xato xabarlari (frontend foydalanuvchiga ko'rsatadi — 11.10).
- Barqarorlik — kutilmagan ma'lumot serverni buzmaydi (2.12-JS).
2. Nazariya — chuqur tushuntirish
2.1. Nima uchun validatsiya (uch sabab)
- Xavfsizlik (14): hacker so'rovga zararli ma'lumot yuboradi (SQL injection —
'; DROP TABLE; XSS —<script>; ulkan payload — DoS). Validatsiya darvozada to'xtatadi. - To'g'rilik: foydalanuvchi xato qiladi (bo'sh email, harf yoshda). Validatsiya aniq xabar beradi.
- Yaxlitlik: DB'ga (6) faqat to'g'ri shakldagi ma'lumot kirsin (yomon ma'lumot keyin muammo).
Oltin qoida (14): server validatsiyasi MAJBURIY. Frontend validatsiyasi 11.10-bob — faqat UX uchun (foydalanuvchiga tez xabar); u xavfsizlik emas (hacker frontend'ni chetlab, to'g'ridan API'ga so'rov yuboradi — 0.4). Ikkalasi ham kerak, lekin backend — haqiqiy himoya.
2.2. Nimani validatsiya qilish kerak
Faqat req.body emas — barcha kirish (LeadWithSkills/best practices):
req.body — POST/PUT/PATCH ma'lumoti (eng muhim)
req.params — route param (/users/:id — id son'mi?)
req.query — filtr/sahifalash (?page=abc — son'mi? — 5.7)
req.headers — ba'zan (masalan API kalit formati)
fayllar — upload (tur, hajm — 5.11)2.3. Validatsiya turlari
- Mavjudlik (presence): maydon bor/bo'sh emasmi (required).
- Tur (type): string/number/boolean 0.1-bob.
- Format: email, URL, telefon, sana (2.13-JS: RegEx).
- Chegara (range): min/max uzunlik, son oralig'i.
- Maxsus (custom): parol = tasdiq paroli; email band emas (DB — 6).
- Sanitatsiya (sanitization): tozalash (trim, kichik harf, HTML olib tashlash — 14).
Validatsiya vs sanitatsiya: validatsiya — "to'g'rimi?" (rad qiladi). Sanitatsiya — "tozala" (o'zgartiradi:
" Ali ""Ali", HTML olib tashlash). Ko'pincha ikkalasi birga.
2.4. Qayerda validatsiya (middleware sifatida)
Validatsiya — middleware 5.6-bob: route handler'dan oldin ishlaydi; noto'g'ri bo'lsa, biznes logikaga o'tkazmaydi (5.6: next yoki javob):
So'rov [validatsiya middleware] route handler (biznes logika)
│ noto'g'ri 400 (to'xtaydi — 5.7)
│ to'g'ri next() (o'tadi — 5.6)2.5. Schema-based validatsiya (zamonaviy yondashuv)
Schema — ma'lumotning shaklini (qaysi maydon, qaysi tur, qaysi qoida) tasvirlovchi obyekt. Zod/Joi schema-based: avval schema yozasiz, keyin ma'lumotni unga solib tekshirasiz:
Schema: { ism: string (min 2), yosh: number (18+), email: email }
Ma'lumot: { ism: "A", yosh: 15, email: "xato" }
tekshir xatolar: ism qisqa, yosh kichik, email noto'g'ri2.6. Zod — zamonaviy, TypeScript-first (tavsiya)
Zod — eng zamonaviy, TypeScript-first validatsiya (zod.dev). Eng katta afzalligi: schema'dan TypeScript tipini avtomatik chiqaradi (infer) — tipni ikki marta yozmaysiz (7: TS):
import { z } from "zod"; // npm install zod (5.2)
const userSchema = z.object({
ism: z.string().min(2, "Ism kamida 2 belgi").max(50),
email: z.string().email("Email noto'g'ri"),
yosh: z.number().int().min(18, "18+ bo'lishi kerak").optional(),
rol: z.enum(["user", "admin"]).default("user"),
});
// Tekshirish — safeParse (xato tashlmaydi — 2.12-JS)
const natija = userSchema.safeParse(req.body);
if (!natija.success) {
// natija.error — xatolar
} else {
const user = natija.data; // tekshirilgan, tur-xavfsiz ma'lumot
}
// TypeScript tipi avtomatik (7)
// type User = z.infer<typeof userSchema>;Nega Zod: TypeScript bilan a'lo (tip + validatsiya bir joyda — DRY); zamonaviy, qulay API; transform/refine kuchli. Yangi loyihalar uchun birinchi tanlov. (Frontend'da React Hook Form bilan ham — 11.10.)
2.7. Zod — kuchli imkoniyatlar
// parse vs safeParse
userSchema.parse(data); // xato bo'lsa THROW (try/catch — 2.12-JS)
userSchema.safeParse(data); // { success, data/error } (throw yo'q)
// transform — tekshirib, o'zgartirish (sanitatsiya — 2.3)
z.string().trim().toLowerCase(); // tozalash
// refine — maxsus qoida (2.3)
z.object({ parol: z.string(), tasdiq: z.string() })
.refine(d => d.parol === d.tasdiq, { message: "Parollar mos emas" });
// coerce — turni majburlash (5.8: env)
z.coerce.number(); // "42" 42 (query string uchun)
// nested, array
z.object({ manzil: z.object({ shahar: z.string() }) }); // ichma-ich (2.8-JS)
z.array(z.string()); // string massivi2.8. Joi — kuchli, klassik
Joi — qadimiy, juda kuchli validatsiya (hapi.js'dan; betterstack). TypeScript tipini avtomatik chiqarmaydi, lekin granular nazorat bilan:
import Joi from "joi"; // npm install joi (5.2)
const schema = Joi.object({
ism: Joi.string().min(2).max(50).required(),
email: Joi.string().email().required(),
yosh: Joi.number().integer().min(18).optional(),
parol: Joi.string().min(8).required(),
tasdiq: Joi.ref("parol"), // boshqa maydonga havola (2.7: refine kabi)
}).with("parol", "tasdiq"); // parol bo'lsa, tasdiq ham
const { error, value } = schema.validate(req.body, { abortEarly: false });
// abortEarly: false BARCHA xatolarni qaytaradi (birinchisida to'xtamaydi)Joi vs Zod: Joi — granular nazorat, mavjud loyihalarda keng; Zod — TypeScript-first (tip infer), zamonaviy. Yangi TS loyihada Zod; mavjud/JS loyihada yoki murakkab shartda Joi.
2.9. express-validator — Express'ga xos
express-validator — validator.js ustiga qurilgan Express middleware (zanjir API):
import { body, param, validationResult } from "express-validator";
app.post("/users",
body("email").isEmail().withMessage("Email noto'g'ri"),
body("ism").trim().isLength({ min: 2 }).withMessage("Ism qisqa"),
body("yosh").optional().isInt({ min: 18 }),
param("id").isMongoId(), // route param (2.2)
(req, res) => {
const xatolar = validationResult(req);
if (!xatolar.isEmpty()) {
return res.status(400).json({ xatolar: xatolar.array() }); // (5.7)
}
// ... to'g'ri ...
}
);express-validator — Express'ga tabiiy (middleware zanjir); o'rganish oson; oddiy API uchun tez yo'l. Lekin schema-based emas (Zod/Joi'dek qayta ishlatish qiyinroq).
2.10. class-validator — dekorator (NestJS — 8)
class-validator — class va dekorator (7.6: TS) asosida; NestJS (8.5: DTO) bilan a'lo:
import { IsEmail, IsString, MinLength, IsInt, Min, IsOptional } from "class-validator";
class CreateUserDto { // DTO (8.5)
@IsString()
@MinLength(2)
ism: string;
@IsEmail()
email: string;
@IsInt()
@Min(18)
@IsOptional()
yosh?: number;
}class-validator — TypeScript + dekorator; NestJS (8) ning standart validatsiyasi (DTO + ValidationPipe — 8.5). Class-based arxitekturaga mos. NestJS'siz kamroq ishlatiladi.
2.11. Validatsiya middleware (DRY — qayta ishlatish)
Har route'da validatsiya kodini takrorlash — yomon (DRY buzilishi — 15.1). Bir marta validatsiya middleware yozing, har joyda ishlating (best practices):
// Zod uchun universal validatsiya middleware
const validate = (schema) => (req, res, next) => {
const natija = schema.safeParse(req.body);
if (!natija.success) {
return res.status(400).json({ // (5.7: 400)
success: false,
error: { code: "VALIDATION", details: natija.error.flatten().fieldErrors },
});
}
req.body = natija.data; // tozalangan ma'lumot (transform — 2.7)
next(); // o'tkaz (5.6)
};
// Ishlatish
app.post("/users", validate(userSchema), createUser); // (5.6)2.12. Xato formatini izchil qilish (5.7)
Validatsiya xatolari izchil shaklda (5.7, 5.10) bo'lsin — frontend 11.10-bob bir xil o'qiydi:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"details": {
"email": ["Email noto'g'ri"],
"ism": ["Ism kamida 2 belgi"]
}
}
}2.13. Sanitatsiya va xavfsizlik (14)
Validatsiyadan tashqari — sanitatsiya (tozalash) muhim (14):
trim — chetdagi bo'shliq (2.6-JS)
toLowerCase — email kichik harf (izchillik)
escape/strip — HTML/script olib tashlash (XSS — 14)
cheklash — maydon uzunligi (DoS — 14); ortiqcha maydonni rad (.strict())Faqat ruxsat etilgan maydonlarni qabul qiling (allowlist): Zod default ortiqcha maydonni o'tkazib yuboradi;
.strict()bilan rad qiladi. Bu — mass assignment hujumidan saqlaydi (foydalanuvchi{ rol: "admin" }yuborib, admin bo'lib olishi — 14).
2.14. Vositalar taqqoslash (qaysi qachon)
| Vosita | Uslub | TypeScript | Qachon |
|---|---|---|---|
| Zod | schema | a'lo (infer) | yangi TS loyiha (tavsiya) |
| Joi | schema | ~ (qo'lda) | murakkab qoida, JS/mavjud |
| express-validator | middleware zanjir | ~ | oddiy Express, tez |
| class-validator | dekorator | NestJS (8) |
Tavsiya: yangi loyihada Zod (TS-first, frontend'da ham — 11.10). NestJS'da class-validator 8.5-bob. Oddiy/tez uchun express-validator.
2.15. Frontend + backend validatsiya (11.10 bilan)
Frontend 11.10-bob: React Hook Form + Zod tez UX (foydalanuvchiga darrov xabar)
Backend (bu bob): MAJBURIY xavfsizlik himoyasi (hacker frontend'ni chetlaydi)
Zod schema'ni ULASHISH mumkin (umumiy paket — frontend + backend bir schema!)Zod'ning ajoyib afzalligi: bir Zod schema'ni ham frontend, ham backendda ishlatish (umumiy paket — 15.4 monorepo). Bir marta yozing, ikki joyda — DRY.
3. Sintaksis — tez ma'lumotnoma
// Zod (tavsiya)
import { z } from "zod";
const schema = z.object({ email: z.string().email(), yosh: z.number().min(18) });
const r = schema.safeParse(data); // { success, data/error }
r.error.flatten().fieldErrors; // xatolar (2.12)
// Validatsiya middleware (2.11)
const validate = (schema) => (req, res, next) => { /* safeParse 400 yoki next */ };
app.post("/x", validate(schema), handler);
// Joi: schema.validate(data, { abortEarly: false }) { error, value }
// express-validator: body("email").isEmail() ... validationResult(req)
// class-validator: @IsEmail() (NestJS — 8)4. Batafsil kod namunalari
Misol 1 — Zod asosiy (2.6)
import { z } from "zod";
const royxatdanOtish = z.object({
ism: z.string().trim().min(2, "Ism kamida 2 belgi").max(50), // trim — sanitatsiya (2.13)
email: z.string().trim().toLowerCase().email("Email noto'g'ri"),
parol: z.string().min(8, "Parol kamida 8 belgi"),
yosh: z.coerce.number().int().min(18).optional(), // coerce (2.7)
});
const natija = royxatdanOtish.safeParse({
ism: " Ali ", email: "ALI@MAIL.UZ", parol: "parol123", yosh: "25",
});
console.log(natija.data);
// { ism: "Ali", email: "ali@mail.uz", parol: "parol123", yosh: 25 }
// trim, toLowerCase, coerce — avtomatik (2.7, 2.13)Misol 2 — Zod refine (parol tasdig'i — 2.7)
const parolSchema = z.object({
parol: z.string().min(8),
tasdiqParol: z.string(),
}).refine((d) => d.parol === d.tasdiqParol, {
message: "Parollar mos emas",
path: ["tasdiqParol"], // xato qaysi maydonga (2.12)
});
const r = parolSchema.safeParse({ parol: "12345678", tasdiqParol: "boshqa" });
console.log(r.success); // false
console.log(r.error.flatten().fieldErrors); // { tasdiqParol: ["Parollar mos emas"] }Misol 3 — Universal validatsiya middleware (2.11, DRY)
// middleware/validate.js
export const validate = (schema, manba = "body") => (req, res, next) => {
const natija = schema.safeParse(req[manba]); // body/query/params (2.2)
if (!natija.success) {
return res.status(400).json({ // (5.7)
success: false,
error: {
code: "VALIDATION_ERROR",
details: natija.error.flatten().fieldErrors, // (2.12)
},
});
}
req[manba] = natija.data; // tozalangan (2.13)
next(); // (5.6)
};
// routes/users.js
import { validate } from "../middleware/validate.js";
router.post("/", validate(userSchema), createUser); // body
router.get("/", validate(querySchema, "query"), getUsers); // query (5.7)Misol 4 — Query validatsiyasi (sahifalash — 5.7)
const querySchema = z.object({
page: z.coerce.number().int().min(1).default(1), // "2" 2 (2.7)
limit: z.coerce.number().int().min(1).max(100).default(20),// max 100 (DoS — 14)
sort: z.string().optional(),
category: z.string().optional(),
});
router.get("/products", validate(querySchema, "query"), (req, res) => {
const { page, limit, sort } = req.query; // endi NUMBER, validatsiyalangan (5.7)
// ... sahifalash ...
});
// GET /products?page=2&limit=20 tozalangan; ?limit=9999 max 100Misol 5 — Param validatsiyasi (2.2)
const idSchema = z.object({
id: z.coerce.number().int().positive("ID musbat son bo'lishi kerak"),
});
router.get("/users/:id", validate(idSchema, "params"), (req, res) => {
const { id } = req.params; // NUMBER, musbat (5.7)
// /users/abc 400; /users/-5 400; /users/5 o'tadi
});Misol 6 — Joi misoli (2.8)
import Joi from "joi";
const schema = Joi.object({
ism: Joi.string().min(2).max(50).required().messages({
"string.min": "Ism kamida 2 belgi",
"any.required": "Ism majburiy",
}),
email: Joi.string().email().required(),
yosh: Joi.number().integer().min(18).max(120),
}).options({ abortEarly: false, stripUnknown: true }); // barcha xato + ortiqcha olib tashlash (2.13)
// Joi middleware
const validateJoi = (schema) => (req, res, next) => {
const { error, value } = schema.validate(req.body);
if (error) {
return res.status(400).json({
xatolar: error.details.map((d) => ({ field: d.path[0], message: d.message })),
});
}
req.body = value;
next();
};Misol 7 — express-validator (2.9)
import { body, validationResult } from "express-validator";
// Validatsiya qoidalari massivi
const userRules = [
body("email").trim().isEmail().withMessage("Email noto'g'ri").normalizeEmail(),
body("ism").trim().isLength({ min: 2 }).withMessage("Ism kamida 2 belgi"),
body("parol").isLength({ min: 8 }).withMessage("Parol kamida 8 belgi"),
body("yosh").optional().isInt({ min: 18 }).toInt(),
];
// Natijani tekshiruvchi middleware (DRY — 2.11)
const checkValidation = (req, res, next) => {
const xatolar = validationResult(req);
if (!xatolar.isEmpty()) {
return res.status(400).json({ xatolar: xatolar.array() });
}
next();
};
app.post("/users", userRules, checkValidation, createUser); // (5.6)Misol 8 — Custom validatsiya (DB tekshiruvi — 2.3)
// Email band emasligini tekshirish (DB — 6)
const emailBoshSchema = z.object({
email: z.string().email(),
}).refine(
async (d) => { // async refine (2.11-JS)
const mavjud = await User.findOne({ email: d.email }); // DB (6)
return !mavjud;
},
{ message: "Email allaqachon ro'yxatdan o'tgan", path: ["email"] } // 409 (5.7)
);
// safeParseAsync ishlatiladi (async uchun)
const natija = await emailBoshSchema.safeParseAsync(req.body);Misol 9 — Mass assignment himoyasi (.strict() — 2.13, 14)
// XAVFLI — ortiqcha maydon o'tadi
const yomon = z.object({ ism: z.string(), email: z.string() });
yomon.parse({ ism: "Ali", email: "a@b.uz", rol: "admin" });
// rol: "admin" — agar keyin Object.assign qilsangiz, foydalanuvchi admin bo'ladi! (14)
// XAVFSIZ — .strict() ortiqcha maydonni rad qiladi
const yaxshi = z.object({ ism: z.string(), email: z.string() }).strict();
yaxshi.safeParse({ ism: "Ali", rol: "admin" }); // success: false (rol ruxsatsiz)
// Yoki Zod default'da ortiqcha maydon o'tkazib yuboriladi (data'da bo'lmaydi)Misol 10 — To'liq ro'yxatdan o'tish (validatsiya + biznes — 2.11)
import { z } from "zod";
import { validate } from "../middleware/validate.js";
const signupSchema = z.object({
ism: z.string().trim().min(2).max(50),
email: z.string().trim().toLowerCase().email(),
parol: z.string().min(8).regex(/[A-Z]/, "Katta harf kerak").regex(/\d/, "Raqam kerak"), // (2.13-JS: RegEx)
}).strict(); // mass assignment himoyasi (2.13)
router.post("/auth/signup", validate(signupSchema), async (req, res) => {
const { ism, email, parol } = req.body; // tozalangan, validatsiyalangan
// Bu yerga FAQAT to'g'ri ma'lumot keladi (darvozadan o'tdi)
// ... email band emasligini tekshiring, parol hash 5.3-bob, DB (6) ...
res.status(201).json({ success: true, data: { ism, email } }); // (5.7)
});5. To'g'ri va noto'g'ri holatlar
1) Faqat frontend validatsiyasi
faqat React'da tekshirib, backend'da ishonish (hacker chetlaydi — 14, 2.1)
backend validatsiyasi MAJBURIY (frontend — qo'shimcha UX)2) Validatsiyasiz req.bodyni ishlatish
// to'g'ridan DB'ga (yomon/zararli ma'lumot — 14)
await User.create(req.body);
// avval validatsiya (middleware — 2.11)
const data = userSchema.parse(req.body);
await User.create(data);3) Ortiqcha maydonni o'tkazish (mass assignment)
// foydalanuvchi { rol: "admin" } yuborib, admin bo'ladi (14, Misol 9)
await User.create(req.body);
// .strict() yoki faqat kerakli maydonlar (2.13)4) Faqat birinchi xatoni qaytarish
// foydalanuvchi har safar bitta xatoni ko'radi (yomon UX)
// BARCHA xatolarni (Zod default; Joi: abortEarly: false — 2.8)5) Xato xabarida ichki ma'lumot oshkor qilish
"column users.password violates constraint" (DB struktura oshkor — 14)
"Parol noto'g'ri" (foydalanuvchi-do'st; texnik — log'da, 5.12)6. Keng tarqalgan xatolar va yechimlari
Xato 1 — req.body undefined (validatsiyada)
Sababi: express.json() yo'q 5.6-bob. Yechimi: app.use(express.json()) route'lardan oldin 5.6-bob.
Xato 2 — Query har doim string, validatsiya o'tmaydi
Sababi: query string 5.7-bob; z.number() string'ni rad etadi. Yechimi: z.coerce.number() (2.7, Misol 4).
Xato 3 — Async validatsiya (DB) ishlamaydi
Sababi: .refine async, lekin safeParse (sync) ishlatildi (2.11-JS). Yechimi: safeParseAsync (Misol 8).
Xato 4 — Ortiqcha maydon DB'ga ketdi
Sababi: validatsiya ortiqchani o'tkazdi (2.13, 14). Yechimi: .strict(); faqat datani ishlating (Zod tozalangan qaytaradi).
Xato 5 — Validatsiya kodi har route'da takrorlanadi
Sababi: middleware'siz (DRY — 2.11). Yechimi: universal validate(schema) middleware (Misol 3).
Xato 6 — class-validator dekoratorlari ishlamaydi
Sababi: reflect-metadata/tsconfig sozlanmagan 7.6-bob. Yechimi: NestJS (8) avtomatik sozlaydi; alohida — experimentalDecorators 7.1-bob.
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- Express 5.6-bob: validatsiya — middleware.
- REST 5.7-bob: 400/422 status; xato formati.
- Error handling 5.10-bob: validatsiya xatolari global handler bilan.
- Env 5.8-bob: Zod bilan env tekshirish.
- Auth 5.15-bob: login/signup validatsiyasi.
- DB (6): custom validatsiya (email band); DB constraint qo'shimcha himoya.
- TypeScript (7): Zod
infer— tip + validatsiya. - NestJS 8.5-bob: class-validator + ValidationPipe + DTO.
- React Hook Form 11.10-bob: frontend Zod (ulashiladigan schema — 2.15).
- Xavfsizlik (14): injection, mass assignment, DoS himoyasi.
8. Eng yaxshi amaliyotlar (best practices)
- Backend validatsiyasi MAJBURIY — "foydalanuvchiga ishonma" (14, 2.1); frontend — qo'shimcha UX.
- Barcha kirishni tekshiring — body, query, params, fayl 2.2-bob.
- Schema-based (Zod) — yangi loyiha; class-validator — NestJS (8); Joi — murakkab/JS.
- Validatsiya — middleware (DRY, route'dan oldin — 2.11, 2.4).
.strict()/ allowlist — mass assignment himoyasi (2.13, 14).- Sanitatsiya (trim, toLowerCase, escape) — validatsiya bilan birga 2.13-bob.
- Barcha xatolarni qaytaring (bitta emas — UX); izchil format (5.7, 2.12).
- Xato xabarida ichki ma'lumot oshkor qilmang (DB struktura — 14, 5-holat).
- Query'da
coerce(string number — 2.7). - Zod schema'ni frontend+backend ulash (DRY — 2.15).
9. Amaliy loyiha: "Validatsiya Qatlami bilan Xavfsiz API"
Validatsiyani professional darajada mustahkamlash.
Maqsad
Zod (yoki Joi) bilan schema-based validatsiya, universal middleware, sanitatsiya va xavfsizlik (mass assignment) himoyasini birlashtirib, mustahkam API darvozasini qurish.
Talablar (requirements)
- Universal validatsiya middleware:
validate(schema, manba)— body/query/params (Misol 3, 2.11); 400 + izchil xato formati (2.12, 5.7). - Resurs schema'lari (Zod): masalan
products/usersuchun create (POST), update (PATCH — partial), query (filtr/sahifalash) schemalari (2.6, Misol 4). - Sanitatsiya: trim, toLowerCase (email),
.strict()(mass assignment — 2.13, Misol 9). - Custom validatsiya: parol tasdig'i (refine — Misol 2), va async (email band — DB — Misol 8).
- Query/param validatsiya:
coercebilan son; sahifalash limit chegarasi (Misol 4, 5). - Barcha xatolar: bitta emas, hammasi; foydalanuvchi-do'st xabarlar (2.12, 5-xato).
- Integratsiya: validatsiyadan o'tgan, tozalangan
req.bodyni ishlating (Misol 10). - (Bonus) Joi yoki express-validator bilan bir endpoint'ni qayta yozib, Zod bilan solishtiring 2.14-bob.
Maslahatlar (hint)
express.json()route'lardan oldin (1-xato, 5.6).- Query/param uchun
z.coerce.number()(2.7, Misol 4). - Async (DB) uchun
safeParseAsync+.refine(Misol 8). .strict()mass assignment uchun (2.13, 14).- Xato:
error.flatten().fieldErrors(Misol 3). - Tozalangan ma'lumot
req.body = natija.data(transform — 2.7).
"Tayyor" mezonlari (acceptance criteria)
- Universal validate middleware (body/query/params).
- Resurs schema'lari (create/update/query).
- Sanitatsiya (trim/toLowerCase) va
.strict()ishlaydi. - Custom (parol tasdig'i) va async (email band) validatsiya.
- Query/param son'ga aylantiriladi; limit cheklangan.
- Barcha xatolar izchil formatda qaytadi.
- Faqat tozalangan ma'lumot biznes logikaga o'tadi.
- Mass assignment himoyalangan.
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda backend himoyasining birinchi chizig'ini — validatsiyani o'rgandik:
- "Foydalanuvchiga ishonma" (14) — backend validatsiyasi MAJBURIY; frontend — qo'shimcha UX.
- Barcha kirish (body/query/params/fayl); validatsiya turlari (mavjudlik/tur/format/chegara/custom); sanitatsiya (tozalash).
- Validatsiya — middleware (route'dan oldin, DRY — 2.11).
- Zod (TS-first, infer, refine, coerce,
.strict()— tavsiya), Joi (kuchli), express-validator (Express zanjir), class-validator (NestJS — 8). - Mass assignment himoyasi (
.strict()— 14); izchil xato formati 5.7-bob; barcha xatolar. - Zod schema'ni frontend+backend ulash (DRY — 11.10).
Keyingi bob — 5.10-bob: Error handling middleware, global error handler. Validatsiyada xatolarni qaytardik; endi butun ilovadagi xatolarni bir joyda, izchil boshqarishni — global error handler, custom error class, async xato — chuqur o'rganamiz. 5.6'dagi error middleware'ni professional darajaga olib chiqamiz.
Foydalanilgan rasmiy/ishonchli manbalar
- zod.dev — Zod schema validation, infer, refine, transform
- joi.dev — Joi validation; express-validator.github.io — express-validator
- class-validator (github) — dekorator validatsiya (NestJS)
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!