RESTful best practices — naming, status codes, idempotency
Muammodan boshlaylik
Bir loyihadagi endpoint lar:
GET /api/getAllProducts
POST /api/product/create
GET /api/Mahsulot/ol?id=5
POST /api/deleteProduct/5
GET /api/orders_list
Har biri boshqacha: fe'l URL da, birlik va ko'plik aralash, katta-kichik harf, o'chirish POST bilan. Frontend dasturchi har bir endpoint uchun hujjatni qayta o'qiydi; yangi xodim qanday nomlashni bilmaydi.
Hayotiy o'xshatma
Shahar manzillari. Yaxshi rejalashtirilgan shaharda manzil tartibli: "Toshkent, Chilonzor tumani, 9-kvartal, 15-uy". Uyni topish uchun xarita shart emas — tuzilmadan tushunasiz. Tartibsiz shaharda har bir uyga yo'lni so'rab-so'rab topasiz. REST qoidalari — API uchun manzil tizimi.
1. URL — resurs (ot), metod — amal (fe'l)
| ❌ | ✅ |
|---|---|
GET /getProducts |
GET /mahsulotlar |
POST /createProduct |
POST /mahsulotlar |
POST /deleteProduct/5 |
DELETE /mahsulotlar/5 |
GET /product/5 |
GET /mahsulotlar/5 |
GET /api/mahsulotlar ro'yxat
GET /api/mahsulotlar/5 bittasi
POST /api/mahsulotlar yaratish
PUT /api/mahsulotlar/5 to'liq yangilash
PATCH /api/mahsulotlar/5 qisman yangilash
DELETE /api/mahsulotlar/5 o'chirish
Qoidalar:
- Ko'plik:
/mahsulotlar,/buyurtmalar - Kichik harf, so'zlar defis bilan:
/yetkazib-berish-manzillari - Oxirida
/siz
2. Ichma-ich resurslar — bir daraja
GET /api/buyurtmalar/42/qatorlar 42-buyurtmaning qatorlari
POST /api/buyurtmalar/42/qatorlar qator qo'shish
GET /api/mijozlar/7/buyurtmalar mijozning buyurtmalari
Chuqur ichma-ichlikdan qoching: /mijozlar/7/buyurtmalar/42/qatorlar/3/mahsulot — o'rniga /qatorlar/3 yoki /mahsulotlar/9.
CRUD ga sig'maydigan amallar
POST /api/buyurtmalar/42/bekor-qilish
POST /api/buyurtmalar/42/tolov
POST /api/foydalanuvchilar/7/parol-tiklash
Holat o'zgartiradigan biznes amal — resurs ostidagi fe'l bilan POST. Bu maqbul va keng tarqalgan.
3. Status kodlar — to'g'ri ishlating
| Holat | Kod |
|---|---|
| O'qish muvaffaqiyatli | 200 OK |
| Yaratildi | 201 Created + Location sarlavhasi |
| Muvaffaqiyatli, body yo'q (DELETE, PUT) | 204 No Content |
| Noto'g'ri so'rov / validatsiya | 400 Bad Request |
| Token yo'q | 401 Unauthorized |
| Huquq yo'q | 403 Forbidden |
| Topilmadi | 404 Not Found |
| Ziddiyat (dublikat, versiya) | 409 Conflict |
| Biznes qoida buzildi | 422 Unprocessable Entity |
| Limit oshdi | 429 Too Many Requests |
| Server xatosi | 500 Internal Server Error |
[HttpPost]
public async Task<ActionResult<MahsulotDto>> Yarat(MahsulotYaratDto dto, CancellationToken ct)
{
var m = await service.YaratAsync(dto, ct);
return CreatedAtAction(nameof(Ol), new { id = m.Id }, m); // 201 + Location
}
[!WARNING] Xatoni
200 OK+{ "success": false, "error": "..." }bilan qaytarmang. HTTP kutubxonalar, monitoring, cache va proxy lar status kodiga qaraydi — 200 ko'rib, "hammasi joyida" deb hisoblaydi.
4. Ro'yxatlar — filtrlash, saralash, sahifalash
GET /api/mahsulotlar?kategoriya=telefon&minNarx=1000000&saralash=-narx&sahifa=2&hajm=20
public record MahsulotSorov(
string? Kategoriya, decimal? MinNarx, string? Saralash,
int Sahifa = 1, int Hajm = 20);
[HttpGet]
public async Task<SahifaJavob<MahsulotDto>> Royxat([FromQuery] MahsulotSorov s, CancellationToken ct)
{
var hajm = Math.Clamp(s.Hajm, 1, 100); // maksimal chegarani majburlash
// ...
}
{
"elementlar": [ { "id": 31, "nomi": "Telefon X" } ],
"sahifa": 2,
"hajm": 20,
"jami": 347
}
[!TIP] Hech qachon cheklanmagan ro'yxat qaytarmang —
GET /api/buyurtmalar2 million qator qaytarib, serverni yiqitishi mumkin. Sukut bo'yicha sahifalash va maksimalhajm(masalan, 100). Juda katta, tez o'zgaradigan to'plamlar uchun — cursor asosidagi sahifalash (?keyingi=eyJpZCI6MTAwfQ).
5. Izchil javob formati
- JSON nomlari — camelCase (ASP.NET Core sukut bo'yicha)
- Sanalar — ISO 8601, UTC:
"2026-11-08T14:30:00Z" - Pul —
decimal; valyuta aniq bo'lsin - Xatolar — ProblemDetails (65-dars)
- Enum lar — satr sifatida (
"Yetkazilmoqda", raqam emas):
builder.Services.AddControllers()
.AddJsonOptions(o => o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
6. Idempotentlik
| Metod | Idempotent? |
|---|---|
| GET, PUT, DELETE | ✅ — bir necha marta = bir marta |
| POST | ❌ — har safar yangi resurs |
Tarmoq uzilib mijoz POST ni qayta yuborsa — ikkita buyurtma. Muhim POST larda (to'lov) — Idempotency-Key sarlavhasi: server kalitni eslab qoladi va takroriy so'rovga avvalgi natijani qaytaradi.
7. Versiyalash va hujjat
- Buzuvchi o'zgarishlar — yangi versiya:
/api/v2/...(73-dars) - Hujjat — OpenAPI/Swagger (72-dars)
Tez-tez uchraydigan xatolar
GET bilan holat o'zgartirish (GET /api/buyurtmalar/5/bekor) — brauzer oldindan yuklashi, crawler yoki cache uni tasodifan chaqiradi.
Entity ni to'g'ridan-to'g'ri qaytarish — ichki maydonlar oshkor; DTO (45-dars).
Javoblarda turli nomlash — product_name, ProductName, productName aralash.
Xulosa
URL — resurs (ko'plikdagi ot, kichik harf, defis), amal — HTTP metodi. Ichma-ichlik — bir daraja; CRUD ga sig'maydigan amallar — POST /resurs/{id}/amal. Status kodlar to'g'ri: 201 + Location, 204, 400/401/403/404/409/422/429; xato — hech qachon 200 bilan emas.
Ro'yxatlar — filtr, saralash va majburiy sahifalash. Izchil format: camelCase, ISO 8601 UTC, ProblemDetails, enum — satr. POST idempotent emas — muhim amallarda Idempotency-Key. Versiyalash va OpenAPI hujjat.
Keyingi dars
72-dars: Swagger / OpenAPI — avtomatik hujjat, Scalar, XML comments