Tarkibga o'tish

09 β€” Xatolarni dizayn qilish

⬅️ Oldingi: 08 β€” Sahifalash, filtrlash, saralash, qidiruv Β· 🏠 README Β· Keyingi: 10 β€” API versiyalash va evolyutsiya ➑️


Bu bobda: API'ning eng ko'p ishlatiladigan, lekin ko'pincha eng kam o'ylangan qismi β€” xato javoblari. Yaxshi xatoni qanday loyihalash: to'g'ri status kod, mashina-o'qiy code, inson-o'qiy xabar, qo'shimcha kontekst. RFC 9457 Problem Details standartini chuqur o'rganamiz, validatsiya xatolarini (ko'p maydon) modellashtiramiz, xato turini status kodga moslaymiz, va xavfsizlik bilan izchillikni ta'minlaymiz.

Halollik / Eslatma: Xato formati uchun asosiy standart β€” RFC 9457 "Problem Details for HTTP APIs" (2023, RFC 7807 ni almashtirgan). Status kod semantikasi RFC 9110 ga tayanadi. Bu yerdagi barcha JSON namunalar valid (tekshirilgan); media type application/problem+json standart. Status tanlovida ba'zi nuanslar (masalan 400 yoki 422) amalda ikkala ko'rinishda ham uchraydi β€” buni halol belgilaymiz. Standartlar versiyasi vaqt bilan o'zgarishi mumkin.


Nega xato dizayni muhim

Tasavvur qiling: siz yangi API'ga ulanyapsiz. So'rov yuborasiz va shunday javob olasiz:

HTTP/1.1 500 Internal Server Error
Content-Type: text/html

<html><body>Something went wrong</body></html>

Endi nima qilasiz? Token noto'g'rimi? Maydon yetishmayaptimi? Server o'chganmi? Hech narsa ma'lum emas. Siz dokumentatsiyani titkilaysiz, taxminlar qilasiz, supportga yozasiz β€” soatlar ketadi.

Mana shu xato dizayni muammosi. Aksariyat dasturchilar API'ning "muvaffaqiyatli" yo'liga (happy path) ko'p vaqt sarflaydi, xatolarni esa oxirgi daqiqada "tashlab qo'yadi". Lekin amalda:

  • Xato javoblari eng ko'p o'qiladi. Integratsiya jarayonida dasturchi muvaffaqiyatli javobni bir marta ko'radi, xatolarni esa o'nlab marta β€” chunki dastlab hamma narsa noto'g'ri ketadi.
  • Yaxshi xato = tezkor tuzatish. Yaxshi loyihalangan xato javobi dasturchiga aniq aytadi: nima noto'g'ri, qayerda, qanday tuzatish. Bu Developer Experience (DX) ning yuragi.
  • Yomon xato = sarflangan vaqt va supportga yuk. "500 Internal Error" hech kimga yordam bermaydi β€” na mijozga, na sizga.

Eslatma: Xato javobini mijoz uchun yozilgan xat deb tasavvur qiling. Maqsad β€” uni o'qigan dasturchi (yoki uning kodi) muammoni mustaqil hal qila olishi. Bu API'ning eng yaxshi "hujjati".

Bu bobda biz xatolarni shunchaki "qaytarish" emas, balki shartnoma sifatida loyihalashni o'rganamiz: bir xil, oldindan aytsa bo'ladigan, mashinaga ham insonga ham tushunarli.


Yaxshi xato javobi nimadan iborat

Yaxshi xato javobida besh element bo'ladi. Birortasi tushib qolsa, javob "yarim" bo'ladi.

# Element Kim uchun Misol
1 To'g'ri status kod Mashina (HTTP qatlami) 422, 404, 409
2 Mashina-o'qiy kod (code) Mijoz mantiqi (if/switch) "ORDER_NOT_FOUND"
3 Inson-o'qiy xabar Loglarni o'qiyotgan dasturchi "Buyurtma topilmadi"
4 Qo'shimcha kontekst Aniq tuzatish uchun qaysi maydon, qiymat, chegara
5 Havola / trace id Debugging, support type URI, trace_id

Keling, har birini ko'rib chiqaylik.

1. To'g'ri status kod. HTTP status kodi β€” xatoning birinchi va eng muhim signali. U mijoz aybi (4xx) yoki server aybi (5xx) ekanini bir qarashda aytadi. Mijozlar (va proksilar, monitoring tizimlari) ko'pincha faqat status kodga qarab harakat qiladi. Status kodlarni chuqurroq 03 β€” HTTP status kodlari bobida ko'rib chiqqansiz; bu bobda ularni xato kontekstiga moslaymiz.

2. Mashina-o'qiy kod. Bu β€” sizning API'ngiz aniqlaydigan barqaror kalit, masalan "INSUFFICIENT_FUNDS". Mijoz kodida if (err.code === "INSUFFICIENT_FUNDS") deb yozadi. Bu kod hech qachon o'zgarmasligi kerak (xabar matni o'zgarsa ham).

3. Inson-o'qiy xabar. Loglarda ko'rinadigan, dasturchiga tushunarli matn. Bu matn o'zgarishi mumkin (tilga tarjima qilinadi, qayta yoziladi) β€” shuning uchun mijoz mantiqi unga tayanmasligi shart.

4. Qo'shimcha kontekst. "Email noto'g'ri" yetarli emas. "email maydoni yaroqli format emas: salom" β€” mana bu foydali. Qaysi maydon, qaysi qiymat, qanday chegara buzilgan.

5. Havola / trace id. Muammo turini tavsiflovchi hujjatga URI (type), va aniq hodisani topish uchun trace_id β€” support bilan gaplashganda bebaho.


Problem Details β€” RFC 9457

Agar har bir API o'z xato formatini o'ylab topsa, dasturchilar har safar yangidan o'rganishlari kerak. Shuning uchun IETF standart format chiqargan.

Standart: RFC 9457 β€” "Problem Details for HTTP APIs" (2023-yil iyul). U eski RFC 7807 ni (2016) almashtirdi (obsoletes). 7807 ni "avvalgi versiyasi" sifatida eslashingiz mumkin, lekin hozir amaldagi standart β€” 9457. Media type: application/problem+json (XML uchun application/problem+xml ham bor, lekin amalda JSON ustun).

RFC 9457 Problem Details tuzilishi

Standart maydonlar

RFC 9457 beshta standart maydonni belgilaydi. Barchasi ixtiyoriy β€” lekin amalda kamida type, title, status berish yaxshi odat.

Maydon Tur Ma'nosi
type URI (string) Muammo turini bildiruvchi barqaror identifikator. Default "about:blank". Odatda hujjatga havola.
title string Qisqa, inson-o'qiy sarlavha. type uchun o'zgarmas xulosa (holatdan holatga emas).
status number HTTP status kodi (javob status bilan mos bo'lsin).
detail string Shu aniq holatga xos tushuntirish (title'dan farqli β€” bu o'zgaruvchan).
instance URI (string) Muammoning shu aniq hodisasiga havola (masalan /orders/7).

Diqqat: title va detail farqini ajrating. title β€” muammo turi uchun barqaror sarlavha ("Mablag' yetarli emas"). detail β€” bu safar nima bo'lganini aytadi ("Hisobda 12000, kerak 50000"). title ni mijoz type o'rniga ham ishlatishi mumkin; detail har safar boshqacha.

Eng oddiy valid Problem Details javobi:

GET /v1/orders/9999 HTTP/1.1
Host: api.example.com
Accept: application/json

HTTP/1.1 404 Not Found
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/not-found",
  "title": "Resurs topilmadi",
  "status": 404,
  "detail": "9999 raqamli buyurtma mavjud emas",
  "instance": "/v1/orders/9999"
}

E'tibor bering: Content-Type β€” application/problem+json, oddiy application/json emas. Bu mijozga "bu xato javobi, uni Problem Details sifatida tahlil qil" deb signal beradi.

Kengaytma maydonlar

RFC 9457 ning eng kuchli tomoni: beshta standart maydonga o'zingizning maydonlaringizni qo'shsangiz bo'ladi. Bular β€” kengaytma maydonlar (extension members).

POST /v1/orders HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>

{"item_id": 42, "quantity": 3}

HTTP/1.1 409 Conflict
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/insufficient-funds",
  "title": "Mablag' yetarli emas",
  "status": 409,
  "detail": "Hisobda 12000 so'm, buyurtma uchun 50000 so'm kerak",
  "instance": "/v1/orders/7",
  "balance": 12000,
  "required": 50000,
  "trace_id": "req-9f2a3c"
}

Bu yerda balance, required, trace_id β€” kengaytma maydonlar. Ular standartda yo'q, lekin RFC 9457 ularni qo'shishga ruxsat beradi.

Trade-off: Kengaytma maydonlar β€” kuch, lekin mas'uliyat ham. Ularni hujjatlang (type URI ortida tavsif bo'lsin). Ularni forward-compatible deb hisoblang: mijoz tanimagan maydonni e'tiborsiz qoldirishi kerak. Yangi kengaytma maydon qo'shish β€” buzmaydigan o'zgarish (breaking emas); maydon olib tashlash yoki ma'nosini o'zgartirish esa β€” buzadi.

Eslatma β€” type URI ochilishi shartmi? Yo'q. RFC type ni shunchaki barqaror identifikator deb belgilaydi β€” uni brauzerda ochib bo'lmasa ham yaroqli. Lekin eng yaxshi amaliyot: shu URI'da haqiqiy hujjat bo'lsin (muammo nima, qanday tuzatish). Bu DX uchun katta yutuq.


Validatsiya xatolari β€” eng keng tarqalgani

API'da eng ko'p uchraydigan xato β€” validatsiya: mijoz yuborgan ma'lumot qoidalarni buzgan. Bu yerda bitta nozik, lekin juda muhim qoida bor.

Anti-pattern: Maydonlarni bittalab tekshirib, birinchi xatoda to'xtab qaytarish. Foydalanuvchi formani to'ldiradi, "email noto'g'ri" oladi, tuzatadi, qayta yuboradi, "parol qisqa" oladi... Bu jirkanch DX.

To'g'ri yondashuv: hamma maydonni bir vaqtda tekshiring, barcha xatolarni errors[] ro'yxati qilib bitta javobda qaytaring.

Validatsiya xatosi javobi

POST /v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json

{"email": "salom", "age": -5, "password": "123"}

HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/validation",
  "title": "Validatsiya muvaffaqiyatsiz",
  "status": 422,
  "detail": "So'rovda 3 ta maydon noto'g'ri",
  "errors": [
    {"field": "email", "code": "INVALID_FORMAT", "message": "Yaroqli email manzil emas"},
    {"field": "age", "code": "OUT_OF_RANGE", "message": "Yosh manfiy bo'lishi mumkin emas"},
    {"field": "password", "code": "TOO_SHORT", "message": "Kamida 8 belgi bo'lishi kerak"}
  ]
}

Har bir xato uchun uch element:

  • field β€” qaysi maydon (ichma-ich bo'lsa, address.city yoki JSON Pointer /address/city).
  • code β€” barqaror mashina-kod (mijoz mantiqi shunga tayanadi).
  • message β€” inson uchun matn (o'zgarishi/tarjima bo'lishi mumkin).

Eslatma: errors[] β€” RFC 9457 ning kengaytma maydoni. Standart uni majburlamaydi, lekin ko'p maydonli validatsiya uchun de-fakto naqsh shu. Ba'zi API'lar errors o'rniga invalid_params (RFC 9457 misolida ham shu nom uchraydi) ishlatadi β€” nomi muhim emas, izchillik muhim.

422 vs 400 β€” halol farq

Bu eng ko'p bahsli savol. Qachon 400 Bad Request, qachon 422 Unprocessable Content?

Holat Status Sabab
JSON buzilgan, o'qib bo'lmaydi ({"a":}) 400 So'rovni umuman tahlil qilib bo'lmadi (sintaktik).
Content-Type noto'g'ri, majburiy maydon umuman yo'q 400 So'rov shakli noto'g'ri.
JSON valid, lekin age: -5 (qoida buzilgan) 422 Sintaksis to'g'ri, lekin semantik xato.
email formati noto'g'ri, qiymat chegaradan tashqari 422 Ma'no jihatdan qayta ishlab bo'lmaydi.

Halollik: RFC 9110 422 Unprocessable Content ni "so'rov to'g'ri shakllangan, lekin semantik xatolar tufayli ko'rsatmalarga amal qilib bo'lmadi" deb belgilaydi β€” shuning uchun semantik validatsiya uchun u yaxshi mos keladi. Lekin amalda ko'p mashhur API'lar (ba'zilari tarixiy sabablarga ko'ra) barcha validatsiya xatolari uchun 400 ishlatadi. Ikkalasi ham qabul qilinadi. Eng muhimi β€” bitta API ichida izchil bo'lish va tanlovni hujjatlash. Bu kitobda biz 400 = buzilgan/o'qib bo'lmas, 422 = valid-lekin-qoidaga-zid deb ajratamiz.


Status kod mosligi

Har bir xato turini to'g'ri status kodga moslash β€” xato dizaynining yadrosi. Quyidagi jadval eng keng tarqalgan moslarni beradi.

Xato turi va status kod mosligi

Xato turi Status Eslatma
Buzilgan/o'qib bo'lmas so'rov 400 Bad Request Sintaktik xato, noto'g'ri JSON.
Semantik validatsiya xatosi 422 Unprocessable Content Valid shakl, buzilgan qoida (yoki 400, izchil bo'lsa).
Autentifikatsiya yo'q/noto'g'ri 401 Unauthorized Aslida "unauthenticated" β€” kim ekaning noma'lum.
Ruxsat yo'q 403 Forbidden Kim ekaning ma'lum, lekin ruxsat yo'q.
Resurs topilmadi 404 Not Found Yo'q yoki ataylab yashirilgan.
Metod qo'llab-quvvatlanmaydi 405 Method Not Allowed Allow sarlavhasi bilan.
Media type qo'llanmaydi 415 Unsupported Media Type Noto'g'ri Content-Type.
Konflikt (holat ziddiyati) 409 Conflict Takror yozuv, bir vaqtda tahrir.
Resurs endi yo'q (butunlay) 410 Gone 404 dan farqli β€” "ataylab o'chirilgan".
Shart talab qilinadi 428 Precondition Required If-Match ni majburlash uchun.
So'rov chegarasi oshdi 429 Too Many Requests Retry-After bilan (14 β€” Rate limiting).
Server ichki xatosi 500 Internal Server Error Kutilmagan bug β€” mijoz aybsiz.
Vaqtincha band/o'chiq 503 Service Unavailable Retry-After bilan.

Asosiy qoida: 4xx = mijoz aybi (so'rovni tuzatsa, qayta urinsa bo'ladi); 5xx = server aybi (mijoz aybsiz, odatda keyinroq qayta urinish kerak).

Diqqat β€” 401 vs 403: Bu ikkisini juda ko'p chalkashtiradi. 401 β€” "men seni tanimadim" (token yo'q/yaroqsiz), odatda WWW-Authenticate sarlavhasi bilan keladi. 403 β€” "men seni tanidim, lekin bu senga mumkin emas". Bu farqni 12 β€” Avtorizatsiya bobi chuqurlashtiradi.

Status kod yetarli emas

Status kod β€” birinchi signal, lekin o'zi yetarli emas. 400 ko'plab turli xatolarni qamraydi. Shuning uchun status kodni doim Problem Details tanasi bilan to'ldiring: aniq type/code, detail, kerakli kontekst. Status β€” keng kategoriya; tana β€” aniq sabab.


Xavfsizlik β€” nimani oshkor qilmaslik

Xato javoblari β€” ma'lumot sizib chiqishining eng keng tarqalgan manbai. Tasavvur qiling, server quyidagini qaytaradi:

{
  "error": "SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'admin@x.uz' for key 'users.email_unique' in /var/www/app/Models/User.php:142"
}

Bu falokat. Bitta xabar bilan hujumchi: ma'lumotlar bazasi turi (MySQL), jadval va ustun nomlari (users.email_unique), ichki fayl yo'llari (/var/www/...), texnologiya stegi va hattoki haqiqiy email manzilni bildi.

Xavfsizlik: Ichki tafsilotlarni mijozga hech qachon oshkor qilmang β€” stack trace, SQL so'rovlari, ichki fayl yo'llari, kutubxona versiyalari, ma'lumotlar bazasi tuzilishi. Bu β€” ma'lumot oshkorligi zaifligi (OWASP API Security Top 10 β€” 2023 da API8: Security Misconfiguration ostida). Mijozga umumiy, xavfsiz xabar bering; to'liq tafsilotni esa server log'ida saqlang va trace_id orqali bog'lang.

To'g'ri yondashuv:

GET /v1/orders/5 HTTP/1.1
Host: api.example.com

HTTP/1.1 500 Internal Server Error
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/internal",
  "title": "Ichki server xatosi",
  "status": 500,
  "detail": "Kutilmagan xato yuz berdi. Iltimos, keyinroq urinib ko'ring.",
  "trace_id": "req-7b1e44d0"
}

Server tomonida esa to'liq log saqlanadi:

{
  "trace_id": "req-7b1e44d0",
  "level": "error",
  "exception": "PDOException",
  "message": "SQLSTATE[23000]: Duplicate entry ...",
  "stack": "/var/www/app/Models/User.php:142 ...",
  "user_id": 1001
}

Endi support mijozdan trace_id ni so'raydi va log'da to'liq tafsilotni topadi β€” mijozga hech narsa oshkor qilmasdan.

Xavfsizlik β€” 404 vs 403: Maxfiy resurslarda 403 ("bor, lekin senga mumkin emas") mavjudlikni oshkor qiladi. Hujumchi 403 olsa, resurs borligini biladi. Shuning uchun ko'p tizimlar atayin 404 beradi β€” "bormi yo'qmi, bilmaysan". Bu ayniqsa boshqa foydalanuvchining obyektiga murojaat (BOLA β€” API1, OWASP 2023) holatida muhim. Bu mavzu 13 β€” API xavfsizligi bobida chuqurlashadi.

Diqqat: Xato xabarlari timing ham oshkor qiladi. "Email topilmadi" va "Parol noto'g'ri" ni ajratish β€” qaysi emaillar ro'yxatdan o'tganini bildiradi (account enumeration). Login xatolarida umumiy "Email yoki parol noto'g'ri" bering.


Izchillik β€” butun API bir xil shaklda

Tasavvur qiling, bitta API'da uch xil xato shakli:

{"error": "not found"}
{"message": "Forbidden", "code": 403}
{"errors": [{"detail": "invalid"}]}

Mijoz har bir endpoint uchun alohida xato tahlilini yozishga majbur. Bu β€” texnik qarz va doimiy bosh og'rig'i.

Standart: Butun API bitta xato shakliga ega bo'lsin. Eng yaxshisi β€” application/problem+json (RFC 9457) ni hamma joyda ishlatish. Bitta type+title+status+detail skeleti, kerak bo'lsa errors[] yoki boshqa kengaytma. Mijoz bir marta tahlilchi yozadi va u hamma xato uchun ishlaydi.

Buni ta'minlashning amaliy yo'li β€” markazlashgan xato handler (middleware/filter). Har bir endpoint o'zicha xato qaytarmaydi; barcha xatolar bitta joyda Problem Details ga aylanadi. Bu β€” 07 β€” So'rov/javob payload bobidagi izchil javob konvensiyalarining tabiiy davomi.


Error code dizayni

Mashina-o'qiy code (yoki type URI) β€” sizning xato shartnomangizning eng barqaror qismi. Uni jiddiy loyihalang.

1. Barqaror va hujjatlangan. code bir marta e'lon qilingach, o'zgartirmang. Mijozlar unga tayanadi. Hammasini hujjatlang.

2. Mashina-do'st format. SCREAMING_SNAKE_CASE keng tarqalgan: ORDER_NOT_FOUND, INSUFFICIENT_FUNDS, RATE_LIMIT_EXCEEDED. Yoki type URI: https://api.x.uz/errors/order-not-found.

3. Matnga tayanmang. Bu eng muhim qoida:

Anti-pattern: Mijoz mantiqini xabar matniga asoslash:

if (response.message === "Order not found") { ... }  // YOMON
Matn o'zgaradi (qayta yoziladi, tarjima qilinadi, kontekst qo'shiladi) va kod sinadi. To'g'risi:
if (response.code === "ORDER_NOT_FOUND") { ... }  // YAXSHI

4. Granularlik to'g'ri bo'lsin. Juda umumiy (ERROR) β€” foydasiz. Juda nozik (har bir holat uchun alohida kod) β€” boshqarib bo'lmas. O'rta yo'l: mijoz boshqacha harakat qilishi kerak bo'lgan har bir holat uchun alohida kod.

Kod Status Qachon
VALIDATION_FAILED 422 Maydon validatsiyasi (errors[] bilan)
UNAUTHENTICATED 401 Token yo'q/yaroqsiz
PERMISSION_DENIED 403 Ruxsat yetmaydi
ORDER_NOT_FOUND 404 Buyurtma topilmadi
IDEMPOTENCY_CONFLICT 409 Bir xil idempotency-key, boshqa tana
RATE_LIMITED 429 Chegara oshdi
INTERNAL_ERROR 500 Kutilmagan server xatosi

Trade-off: type URI (RFC 9457) yoki qisqa code string? URI β€” standartga to'liq mos, hujjatga havola qiladi, global noyob. code β€” yozish/o'qish qulayroq, mijoz switch'i qisqaroq. Ko'pchilik ikkalasini ham beradi: type (URI, standart) + qo'shimcha code (qisqa kalit). Kichik ichki API uchun code yetarli; katta public API uchun type URI tavsiya etiladi.


To'liq misol β€” barchasi birga

Keling, yaxshi loyihalangan to'liq xato javobini ko'raylik (type + code + detail + kontekst + trace_id):

POST /v1/payments HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>
Idempotency-Key: a1b2c3d4

{"amount": 50000, "currency": "UZS", "card_id": "crd_99"}

HTTP/1.1 409 Conflict
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/insufficient-funds",
  "code": "INSUFFICIENT_FUNDS",
  "title": "Mablag' yetarli emas",
  "status": 409,
  "detail": "Kartada 12000 UZS mavjud, 50000 UZS kerak",
  "instance": "/v1/payments/pay_7f3a",
  "balance": 12000,
  "required": 50000,
  "currency": "UZS",
  "trace_id": "req-9f2a3c"
}

Bu javob mukammal: status (409) kategoriyani, type/code aniq sababni, title/detail insonga, balance/required aniq kontekstni, trace_id debuggingni beradi. Mijoz buni mustaqil hal qila oladi β€” supportga yozish shart emas.


Asosiy g'oyalar (bobni qisqacha)

  • Xato dizayni = DX. Xatolar API'ning eng ko'p o'qiladigan qismi. Yaxshi xato dasturchiga nima, qayerda, qanday tuzatishni aytadi.
  • Besh element: to'g'ri status kod + mashina-code + inson-xabar + kontekst + trace_id/havola.
  • RFC 9457 Problem Details β€” standart format. application/problem+json, maydonlar: type, title, status, detail, instance + kengaytmalar. RFC 7807 ni almashtirgan.
  • Validatsiya: hamma maydonni bir vaqtda tekshir, errors[] (field+code+message) qilib bitta javobda qaytar.
  • 422 vs 400: 400 = o'qib bo'lmas/sintaktik; 422 = valid-lekin-semantik-xato. Ikkalasi ham amalda; izchil bo'l.
  • 401 vs 403: 401 = tanimadim; 403 = tanidim, lekin mumkin emas. Maxfiy resursda 404 mavjudlikni yashiradi.
  • Xavfsizlik: stack trace/SQL/ichki yo'lni mijozga bermang; log'da to'liq saqla + trace_id ber.
  • Izchillik: butun API bitta xato shaklida β€” markaziy handler bilan.
  • code barqaror, hujjatlangan, mashina-do'st. Mijoz matnga emas, codega tayanadi.

Mashqlar

Oson

1-mashq. Quyidagi har bir holat uchun to'g'ri HTTP status kodini tanlang: (a) Foydalanuvchi yuborgan JSON buzilgan, tahlil qilib bo'lmaydi. (b) Token umuman yuborilmagan. (c) Foydalanuvchi boshqa odamning buyurtmasini o'chirishga urinmoqda (token yaroqli, lekin ruxsat yo'q). (d) /v1/orders/9999 so'raldi, bunday buyurtma yo'q. (e) email maydoni formati noto'g'ri (qolgan JSON valid).

2-mashq. Quyidagi xato javobi nimasi bilan yomon? Kamida 3 ta muammoni sanab bering.

{"error": "Error 500: SQLSTATE[42S02] Table 'shop.ordrs' doesn't exist in /app/db.php line 88"}

O'rta

3-mashq. GET /v1/orders/777 so'rovi uchun, bunday buyurtma yo'qligi holatida, to'liq valid RFC 9457 Problem Details javobini yozing (status liniyasi + Content-Type + JSON tanasi). Barcha 5 standart maydonni ishlating.

4-mashq. Quyidagi so'rov uchun 422 validatsiya javobini errors[] bilan yozing. So'rov: {"username": "ab", "email": "yoq", "age": 200}. Qoidalar: username kamida 3 belgi; email yaroqli format; age 0..150 oralig'ida. Har bir xato uchun field, code, message bering.

5-mashq. Bir to'lov API uchun 6 ta error code dizayn qiling (code nomi + status + qachon ishlatilishini bitta jumlada). Nega code ni xabar matnidan ajratish kerakligini 1-2 jumlada tushuntiring.

Qiyin

6-mashq. Bir API barcha xatolar uchun 200 OK qaytaradi va xatoni tanada {"success": false, "error": "..."} shaklida beradi. Bu anti-naqshning kamida 3 ta zararini tushuntiring va uni to'g'ri dizaynga qayta loyihalang (qaysi statuslar, qaysi format).

7-mashq. Bir tizim maxfiy hujjatlar API'siga ega. Foydalanuvchi GET /v1/documents/42 so'raydi, lekin 42-hujjat boshqa foydalanuvchiniki. Xavfsizlik nuqtai nazaridan 403 va 404 orasidan qaysi birini tanlaysiz va nega? Tanlovingiz uchun valid Problem Details javobini yozing. (OWASP 2023 dagi qaysi xavf bilan bog'liq?)

8-mashq. Bir kompaniya yangi API quryapti va 30+ endpointda izchil xato modeli xohlaydi. Butun API uchun bitta xato shartnomasini loyihalang: (a) standart shakl (qaysi maydonlar), (b) 400 va 422 qachon, (c) validatsiya errors[] strukturasi, (d) xavfsizlik qoidasi, (e) buni qanday qilib markazlashtirib ta'minlash. Misol javoblar bilan ko'rsating.

Yechimlar

1-mashq yechimi

(a) 400 Bad Request β€” JSON buzilgan, sintaktik xato, so'rovni tahlil qilib bo'lmaydi. (b) 401 Unauthorized β€” autentifikatsiya yo'q ("unauthenticated"); odatda WWW-Authenticate sarlavhasi bilan. (c) 403 Forbidden β€” tanidim (token yaroqli), lekin ruxsat yo'q. (Maxfiylik xohlansa, 404 ham mumkin β€” 7-mashqqa qarang.) (d) 404 Not Found β€” resurs mavjud emas. (e) 422 Unprocessable Content β€” JSON valid (sintaksis to'g'ri), lekin semantik qoida buzilgan. (Agar API izchil ravishda 400 ishlatsa, 400 ham qabul qilinadi β€” muhimi izchillik.)

2-mashq yechimi

Muammolar: 1. Ma'lumot oshkorligi (xavfsizlik): SQL holati (SQLSTATE), jadval nomi (shop.ordrs), ichki fayl yo'li (/app/db.php) va satr raqami oshkor qilingan β€” OWASP API8 (Security Misconfiguration). Hujumchiga sovg'a. 2. Status tanada takrorlangan: "Error 500" matn ichida β€” bu HTTP status liniyasida bo'lishi kerak, mashina o'qiy maydonda emas. 3. Mashina-o'qiy code yo'q: mijoz mantiqi tayanadigan barqaror kalit yo'q. 4. Foydasiz inson xabari: dasturchiga "nima qilay?"ni aytmaydi, faqat ichki bug'ni ko'rsatadi. 5. trace_id yo'q: support uchun log'ga bog'lovchi yo'q. 6. Noto'g'ri Content-Type ehtimoli: application/problem+json emas.

To'g'ri: umumiy 500 Problem Details (yuqoridagi "Xavfsizlik" bo'limidagi misol), to'liq SQL xatosi esa faqat server log'ida + trace_id.

3-mashq yechimi

GET /v1/orders/777 HTTP/1.1
Host: api.example.com
Accept: application/json

HTTP/1.1 404 Not Found
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/order-not-found",
  "title": "Buyurtma topilmadi",
  "status": 404,
  "detail": "777 raqamli buyurtma mavjud emas",
  "instance": "/v1/orders/777"
}

type (barqaror URI), title (o'zgarmas sarlavha), status (404, status liniyasiga mos), detail (shu holatga xos), instance (aniq URI) β€” beshtasi ham bor. Content-Type = application/problem+json.

4-mashq yechimi

HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/validation",
  "title": "Validatsiya muvaffaqiyatsiz",
  "status": 422,
  "detail": "So'rovda 3 ta maydon noto'g'ri",
  "errors": [
    {"field": "username", "code": "TOO_SHORT", "message": "Foydalanuvchi nomi kamida 3 belgi bo'lishi kerak"},
    {"field": "email", "code": "INVALID_FORMAT", "message": "Yaroqli email manzil emas"},
    {"field": "age", "code": "OUT_OF_RANGE", "message": "Yosh 0 va 150 oralig'ida bo'lishi kerak"}
  ]
}

Uchchala maydon ham bir vaqtda tekshirilgan va bitta javobda qaytarilgan. Har birida field + barqaror code + inson-message.

5-mashq yechimi

To'lov API uchun 6 ta error code:

code Status Qachon
VALIDATION_FAILED 422 Yuborilgan to'lov maydonlari qoidalarni buzdi (summa, valyuta...).
INSUFFICIENT_FUNDS 409 Kartada/hisobda yetarli mablag' yo'q.
CARD_DECLINED 402 Bank kartani rad etdi (402 Payment Required).
PAYMENT_NOT_FOUND 404 Berilgan ID bo'yicha to'lov topilmadi.
IDEMPOTENCY_CONFLICT 409 Bir xil Idempotency-Key, lekin boshqa tana yuborildi.
RATE_LIMITED 429 So'rov chegarasi oshdi (Retry-After bilan).

Nega code ni matndan ajratish kerak: xabar matni o'zgaradi β€” uni qayta yozadilar, boshqa tilga tarjima qiladilar, kontekst qo'shadilar. Agar mijoz if (msg === "...") deb yozsa, matn o'zgargan zahoti kodi buziladi. code esa β€” shartnomaning barqaror qismi: bir marta e'lon qilinib, hech qachon o'zgarmaydi, shuning uchun mijoz mantiqi unga ishonchli tayanadi.

6-mashq yechimi

200 + {"success": false} anti-naqshning zararlari: 1. HTTP semantikasi buziladi: monitoring, proksilar, retry kutubxonalari, CDN'lar β€” barchasi 2xxni "muvaffaqiyat" deb biladi. Ular xatoni "ko'rmaydi", noto'g'ri keshlaydi, qayta urinmaydi. Xato sezilmay qoladi. 2. Mijoz har safar tanani ochishga majbur: status kodga qarab tez qaror qilib bo'lmaydi; har javobni parse qilib successni tekshirish kerak. Generik HTTP klientlar (avtomatik throw on 4xx/5xx) ishlamaydi. 3. Statistika va alerting buziladi: "xato darajasi" status kodga asoslanadi; hamma narsa 200 bo'lsa, dashboard'da xato ko'rinmaydi β€” incidentlar yashirin qoladi.

Qayta dizayn: xato kategoriyasiga mos 4xx/5xx status qaytaring va tanada RFC 9457 Problem Details bering:

HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/validation",
  "title": "Validatsiya muvaffaqiyatsiz",
  "status": 422,
  "detail": "email maydoni yaroqli emas",
  "errors": [{"field": "email", "code": "INVALID_FORMAT", "message": "Yaroqli email manzil emas"}]
}
Endi status xatoni bildiradi, format izchil va standart, infratuzilma to'g'ri ishlaydi.

7-mashq yechimi

Tanlov: 404 Not Found. Sabab: 403 "hujjat bor, lekin senga mumkin emas" deb mavjudlikni oshkor qiladi. Hujumchi turli ID'larni sinab 403 vs 404 farqidan qaysi hujjatlar mavjudligini xaritalashi mumkin. Maxfiy resurslarda begona foydalanuvchiga 404 berib, "bormi-yo'qmi bilmaysan" deyish ma'lumot sizishini to'sadi.

Bu OWASP API Security Top 10 β€” 2023 dagi API1: Broken Object Level Authorization (BOLA) bilan bog'liq β€” eng keng tarqalgan API zaifligi (boshqa foydalanuvchi obyektiga ruxsatsiz kirish).

GET /v1/documents/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer <token>

HTTP/1.1 404 Not Found
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/not-found",
  "title": "Resurs topilmadi",
  "status": 404,
  "detail": "So'ralgan hujjat mavjud emas",
  "instance": "/v1/documents/42",
  "trace_id": "req-3c8a11"
}

Eslatma: server log'ida haqiqiy sababni (ruxsat rad etilishi, qaysi foydalanuvchi) trace_id bilan saqlang β€” audit uchun zarur, lekin mijozga 403 "hujjat bor" deb aytmang.

8-mashq yechimi

Butun API uchun izchil xato shartnomasi:

(a) Standart shakl β€” har bir xato application/problem+json (RFC 9457):

{
  "type": "https://api.example.com/errors/<turi>",
  "code": "MACHINE_CODE",
  "title": "Inson-o'qiy sarlavha",
  "status": 422,
  "detail": "Shu holatga xos tushuntirish",
  "instance": "/v1/...",
  "trace_id": "req-..."
}
type+title+status doim; detail/instance/trace_id mavjud bo'lsa; code β€” qisqa mashina kaliti.

(b) 400 vs 422: 400 = so'rovni o'qib/parse qilib bo'lmadi (buzilgan JSON, noto'g'ri Content-Type, yetishmayotgan tana). 422 = so'rov valid shaklda, lekin semantik qoida buzilgan (maydon validatsiyasi). Bu farq butun API'da bir xil qo'llaniladi va hujjatlanadi.

(c) Validatsiya errors[]:

{
  "type": "https://api.example.com/errors/validation",
  "code": "VALIDATION_FAILED",
  "title": "Validatsiya muvaffaqiyatsiz",
  "status": 422,
  "errors": [
    {"field": "<maydon>", "code": "<QOIDA>", "message": "<tushuntirish>"}
  ]
}
Hamma maydon bir vaqtda tekshiriladi; field ichma-ich uchun nuqtali yoki JSON Pointer.

(d) Xavfsizlik qoidasi: stack trace/SQL/ichki yo'l hech qachon tanada emas β€” faqat log'da + trace_id. Maxfiy obyektlarda begonaga 404. Login xatolarida umumiy "email yoki parol noto'g'ri".

(e) Markazlashtirish: bitta xato handler middleware β€” barcha tashlangan xatolarni (exception) ushlaydi va yuqoridagi shaklga aylantiradi. Endpointlar hech qachon xatoni qo'lda formatlamaydi; ular faqat tipik xato obyektini (yoki exception) tashlaydi, handler uni Problem Details ga o'giradi. Shu tariqa 30+ endpoint avtomatik izchil bo'ladi va yangi endpoint qo'shilganda ham shakl o'zi to'g'ri keladi.

Misol β€” bitta to'g'ri javob:

HTTP/1.1 409 Conflict
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/duplicate-email",
  "code": "DUPLICATE_EMAIL",
  "title": "Email band",
  "status": 409,
  "detail": "Bu email allaqachon ro'yxatdan o'tgan",
  "instance": "/v1/users",
  "trace_id": "req-5d2f"
}


⬅️ Oldingi: 08 β€” Sahifalash, filtrlash, saralash, qidiruv Β· 🏠 README Β· Keyingi: 10 β€” API versiyalash va evolyutsiya ➑️