WisarWisar
Dasturlash kitobi/5-QISM — Nodejs16 daqiqa

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)

  1. Xavfsizlik (14): hacker so'rovga zararli ma'lumot yuboradi (SQL injection — '; DROP TABLE; XSS — <script>; ulkan payload — DoS). Validatsiya darvozada to'xtatadi.
  2. To'g'rilik: foydalanuvchi xato qiladi (bo'sh email, harf yoshda). Validatsiya aniq xabar beradi.
  3. 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):

text
  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):

text
  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:

text
  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'ri

2.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):

js
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

js
// 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 massivi

2.8. Joi — kuchli, klassik

Joi — qadimiy, juda kuchli validatsiya (hapi.js'dan; betterstack). TypeScript tipini avtomatik chiqarmaydi, lekin granular nazorat bilan:

js
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):

js
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:

ts
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):

js
// 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:

json
{
  "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):

text
  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)

text
  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

js
// 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)

js
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)

js
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)

js
// 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)

js
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 100

Misol 5 — Param validatsiyasi (2.2)

js
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)

js
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)

js
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)

js
// 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)

js
//  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)

js
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

text
 faqat React'da tekshirib, backend'da ishonish (hacker chetlaydi — 14, 2.1)
 backend validatsiyasi MAJBURIY (frontend — qo'shimcha UX)

2) Validatsiyasiz req.bodyni ishlatish

js
//  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)

js
//  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

js
//  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

text
 "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)

  1. Universal validatsiya middleware: validate(schema, manba) — body/query/params (Misol 3, 2.11); 400 + izchil xato formati (2.12, 5.7).
  2. Resurs schema'lari (Zod): masalan products/users uchun create (POST), update (PATCH — partial), query (filtr/sahifalash) schemalari (2.6, Misol 4).
  3. Sanitatsiya: trim, toLowerCase (email), .strict() (mass assignment — 2.13, Misol 9).
  4. Custom validatsiya: parol tasdig'i (refine — Misol 2), va async (email band — DB — Misol 8).
  5. Query/param validatsiya: coerce bilan son; sahifalash limit chegarasi (Misol 4, 5).
  6. Barcha xatolar: bitta emas, hammasi; foydalanuvchi-do'st xabarlar (2.12, 5-xato).
  7. Integratsiya: validatsiyadan o'tgan, tozalangan req.bodyni ishlating (Misol 10).
  8. (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!
5.9-bob: Validatsiya — express-validator, Joi, Zod, class-validator — Wisar