Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Yo'l parametrlari
- 2.2. So'rov parametrlari
- 2.3. Ixtiyoriy va majburiy
- 2.4. Tur aylantirish
- 2.5. Parametr validatsiyasi
- 2.6. Annotated sintaksisi
- 2.7. Parametr tartibi va aralashtirish
- 2.8. Javob va status kod
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Yo'l va so'rov parametrlari
- Misol 2 — Parametr validatsiyasi (Query, Path)
- Misol 3 — Ixtiyoriy parametrlar va filtr
- Misol 4 — Amaliy: filtrlash, saralash, sahifalash
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
20.4-dars: Route va parametrlar
20-QISM — WEB-BACKEND (FastAPI) · 4-dars
1. Kirish va motivatsiya
Birinchi FastAPI ilovani yaratdik 20.3-bob. Endi endpointlar ma'lumot qabul qilishni — parametrlarni o'rganamiz. Real API'da so'rovlar ma'lumot tashiydi: /kurslar/5 — qaysi kurs (yo'l parametri); /kurslar?til=uz&sahifa=2 — filtr va sahifalash (so'rov parametrlari). FastAPI bu parametrlarni tip belgilari bilan qabul qiladi, tekshiradi va aylantiradi — avtomatik.
Parametrlar API'ni moslashuvchan qiladi: bir endpoint turli kirish bilan turli natija beradi. Ularni to'g'ri loyihalash — REST API dizaynining muhim qismi.
Real vaziyat. Bir jamoa qidiruv endpointi yozdi, lekin parametrlarni tekshirmasdi: sahifa manfiy bo'lsa baza xatosi, hajm 10000 bo'lsa server osilib qolardi, qidiruv so'zi bo'sh bo'lsa barcha ma'lumot qaytardi. Ular FastAPI validatsiyasini qo'shdi: sahifa >= 1, hajm <= 100, qidiruv min_length=2. Endi noto'g'ri so'rov 422 aniq xato beradi (server osilmaydi), va cheklovlar hujjatda avtomatik ko'rinadi. Parametr validatsiyasi API'ni mustahkam qildi.
Bu darsda route parametrlarini — yo'l va so'rov parametrlarini o'rganamiz.
Bu darsda:
- Yo'l parametrlari (
{kurs_id}) - So'rov parametrlari (
?til=uz) - Ixtiyoriy va majburiy parametrlar
- Standart qiymatlar
- Parametr validatsiyasi (
Query,Path) - Tur aylantirish
- Parametr tartibi
- Amaliy: filtrlash va sahifalash
ℹ Misollarda FastAPI
TestClientbilan sinaladi.
2. Nazariya — chuqur tushuntirish
2.1. Yo'l parametrlari
Yo'l parametri — URL yo'lidagi o'zgaruvchi qism ({...}):
@app.get("/kurslar/{kurs_id}")
def kurs(kurs_id: int): # {kurs_id} → funksiya parametri
return {"id": kurs_id}| Element | Ma'nosi |
|---|---|
{kurs_id} |
Yo'ldagi o'zgaruvchi |
kurs_id: int |
Tur (validatsiya + aylantirish) |
/kurslar/5 |
kurs_id = 5 |
Yo'l parametrlari — resursni aniqlash uchun (/kurslar/5 — 5-kurs). Ular majburiy (yo'lning bir qismi).
2.2. So'rov parametrlari
So'rov parametri — URL'ning ? dan keyingi qismi 20.1-bob:
@app.get("/kurslar")
def kurslar(til: str = "uz", sahifa: int = 1): # ?til=uz&sahifa=2
return {"til": til, "sahifa": sahifa}| Element | Ma'nosi |
|---|---|
| Funksiya parametri (yo'lda yo'q) | So'rov parametri |
til: str = "uz" |
Ixtiyoriy, standart "uz" |
?til=en&sahifa=2 |
til="en", sahifa=2 |
So'rov parametrlari — to'plamni sozlash (filtr, saralash, sahifalash). Ular ko'pincha ixtiyoriy (standart qiymatli).
2.3. Ixtiyoriy va majburiy
| Parametr | Majburiy? |
|---|---|
| Standart qiymatsiz | Majburiy |
| Standart qiymatli | Ixtiyoriy |
str | None = None |
Ixtiyoriy (None bo'lishi mumkin) |
def qidir(q: str): # majburiy (standartsiz)
def sahifala(sahifa: int = 1): # ixtiyoriy (standart 1)
def filtr(til: str | None = None): # ixtiyoriy (None bo'lishi mumkin) Majburiy so'rov parametri berilmasa — 422 xato. Ixtiyoriy — standart yoki None.
2.4. Tur aylantirish
FastAPI parametrlarni tip belgisiga qarab aylantiradi:
| Tip belgisi | Kirish | Natija |
|---|---|---|
int |
"5" |
5 (int) |
float |
"2.5" |
2.5 |
bool |
"true", "1" |
True |
str |
"uz" |
"uz" |
URL parametrlari matn bo'lsa ham, FastAPI ularni tipga aylantiradi; aylantirib bo'lmasa 422.
2.5. Parametr validatsiyasi
Query va Path bilan qo'shimcha tekshiruvlar:
from fastapi import Query, Path
from typing import Annotated
@app.get("/kurslar/{kurs_id}")
def kurs(
kurs_id: Annotated[int, Path(ge=1)], # >= 1
sahifa: Annotated[int, Query(ge=1, le=100)] = 1, # 1-100
q: Annotated[str, Query(min_length=2, max_length=50)] = "",
):
...| Cheklov | Ma'nosi |
|---|---|
ge, gt |
>= / > (son) |
le, lt |
<= / < (son) |
min_length, max_length |
Satr uzunligi |
pattern |
Regex (4-qism) |
Validatsiya cheklovlari hujjatda (/docs) avtomatik ko'rinadi va buzilsa 422 beradi.
2.6. Annotated sintaksisi
Zamonaviy FastAPI Annotated (13-qism) ishlatadi:
# eski:
sahifa: int = Query(default=1, ge=1)
# zamonaviy (tavsiya):
sahifa: Annotated[int, Query(ge=1)] = 1 Annotated[tip, Query(...)] — tur va validatsiyani ajratadi; standart qiymat = bilan. Bu aniqroq va tavsiya etiladi.
2.7. Parametr tartibi va aralashtirish
Bir endpoint yo'l va so'rov parametrlarini birga qabul qiladi:
@app.get("/kurslar/{kurs_id}/darslar")
def darslar(kurs_id: int, sahifa: int = 1, til: str = "uz"):
# kurs_id — yo'l; sahifa, til — so'rov
... FastAPI qaysi parametr yo'lda ({...} bor) va qaysi so'rovda ekanini avtomatik aniqlaydi. Yo'ldagi nom — yo'l parametri, qolgani so'rov.
2.8. Javob va status kod
from fastapi import HTTPException
@app.get("/kurslar/{kurs_id}")
def kurs(kurs_id: int):
if kurs_id not in KURSLAR:
raise HTTPException(status_code=404, detail="topilmadi")
return KURSLAR[kurs_id] Parametr topilsa — natija (200); topilmasa — HTTPException(404). To'g'ri status kod 20.1-bob muhim.
3. Tez ma'lumotnoma
from fastapi import FastAPI, Query, Path
from typing import Annotated
@app.get("/kurslar/{kurs_id}")
def kurs(
kurs_id: Annotated[int, Path(ge=1)], # yo'l parametri
til: str = "uz", # so'rov (ixtiyoriy)
sahifa: Annotated[int, Query(ge=1, le=100)] = 1,
q: str | None = None, # ixtiyoriy (None)
):
...Qoidalar
yo'l parametri ({kurs_id}) — resursni aniqlash (majburiy)
so'rov parametri (?til=uz) — sozlash (ko'pincha ixtiyoriy)
standartsiz — majburiy; standartli — ixtiyoriy
tip belgisi → aylantirish + validatsiya
Query/Path — qo'shimcha tekshiruv (ge, le, min_length)
Annotated[tip, Query(...)] — zamonaviy sintaksis4. Batafsil misollar
Misollarda FastAPI
TestClientbilan sinaladi.
Misol 1 — Yo'l va so'rov parametrlari
"""yo'l parametri ({kurs_id}); so'rov parametrlari (til, sahifa); ixtiyoriy vs majburiy; standart qiymatlar; tur aylantirish."""
import warnings
warnings.filterwarnings("ignore")
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/kurslar/{kurs_id}")
def kurs(kurs_id: int, til: str = "uz", batafsil: bool = False):
return {"id": kurs_id, "til": til, "batafsil": batafsil}
def main() -> None:
client = TestClient(app)
print("=== 1. Yo'l parametri ===")
print(f" /kurslar/5 → {client.get('/kurslar/5').json()}")
print("\n=== 2. So'rov parametrlari ===")
print(f" /kurslar/5?til=en → {client.get('/kurslar/5?til=en').json()}")
print(f" /kurslar/5?til=en&batafsil=true → {client.get('/kurslar/5?til=en&batafsil=true').json()}")
print("\n=== 3. Standart qiymatlar ===")
print(f" /kurslar/5 (til va batafsil sukut): {client.get('/kurslar/5').json()}")
print("\n=== 4. Tur aylantirish ===")
javob = client.get("/kurslar/5?batafsil=1").json()
print(f" batafsil=1 → {javob['batafsil']} (bool: {type(javob['batafsil']).__name__})")
javob = client.get("/kurslar/42").json()
print(f" kurs_id '42' → {javob['id']} (int: {type(javob['id']).__name__})")
print(" ⭐ yo'l parametri — resurs; so'rov parametri — sozlash")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Yo'l parametri ===
/kurslar/5 → {'id': 5, 'til': 'uz', 'batafsil': False}
=== 2. So'rov parametrlari ===
/kurslar/5?til=en → {'id': 5, 'til': 'en', 'batafsil': False}
/kurslar/5?til=en&batafsil=true → {'id': 5, 'til': 'en', 'batafsil': True}
=== 3. Standart qiymatlar ===
/kurslar/5 (til va batafsil sukut): {'id': 5, 'til': 'uz', 'batafsil': False}
=== 4. Tur aylantirish ===
batafsil=1 → True (bool: bool)
kurs_id '42' → 42 (int: int)
⭐ yo'l parametri — resurs; so'rov parametri — sozlashNima ko'rsatdi: 2.1, 2.2, 2.3, 2.4-bo'limlar.
Misol 2 — Parametr validatsiyasi (Query, Path)
"""Query va Path bilan validatsiya: ge/le (son oralig'i), min_length/max_length (satr); buzilsa 422; cheklovlar hujjatda."""
import warnings
warnings.filterwarnings("ignore")
from typing import Annotated
from fastapi import FastAPI, Path, Query
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/kurslar/{kurs_id}")
def kurs(
kurs_id: Annotated[int, Path(ge=1)],
sahifa: Annotated[int, Query(ge=1, le=100)] = 1,
):
return {"id": kurs_id, "sahifa": sahifa}
@app.get("/qidir")
def qidir(q: Annotated[str, Query(min_length=2, max_length=20)]):
return {"q": q, "natija": []}
def main() -> None:
client = TestClient(app)
print("=== 1. To'g'ri parametrlar ===")
print(f" /kurslar/5?sahifa=3 → {client.get('/kurslar/5?sahifa=3').json()}")
print("\n=== 2. ⚠️ Path ge=1 buzilishi ===")
javob = client.get("/kurslar/0")
print(f" /kurslar/0 → status {javob.status_code} (kurs_id >= 1 kerak)")
print("\n=== 3. ⚠️ Query le=100 buzilishi ===")
javob = client.get("/kurslar/5?sahifa=200")
print(f" /kurslar/5?sahifa=200 → status {javob.status_code} (sahifa <= 100)")
print("\n=== 4. ⚠️ Satr uzunligi ===")
print(f" /qidir (q majburiy) → status {client.get('/qidir').status_code}")
print(f" /qidir?q=a (juda qisqa) → status {client.get('/qidir?q=a').status_code}")
print(f" /qidir?q=python (to'g'ri) → {client.get('/qidir?q=python').json()}")
print(" ⭐ Query/Path validatsiyasi — noto'g'ri kirish 422 (server osilmaydi)")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. To'g'ri parametrlar ===
/kurslar/5?sahifa=3 → {'id': 5, 'sahifa': 3}
=== 2. ⚠️ Path ge=1 buzilishi ===
/kurslar/0 → status 422 (kurs_id >= 1 kerak)
=== 3. ⚠️ Query le=100 buzilishi ===
/kurslar/5?sahifa=200 → status 422 (sahifa <= 100)
=== 4. ⚠️ Satr uzunligi ===
/qidir (q majburiy) → status 422
/qidir?q=a (juda qisqa) → status 422
/qidir?q=python (to'g'ri) → {'q': 'python', 'natija': []}
⭐ Query/Path validatsiyasi — noto'g'ri kirish 422 (server osilmaydi)Nima ko'rsatdi: 2.5, 2.6-bo'limlar.
Misol 3 — Ixtiyoriy parametrlar va filtr
"""ixtiyoriy parametrlar (None); bir necha filtr; standart qiymatlar; None tekshiruvi; kombinatsiyalangan filtr."""
import warnings
warnings.filterwarnings("ignore")
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
KURSLAR = [
{"id": 1, "nom": "Python", "til": "uz", "daraja": "boshlangich"},
{"id": 2, "nom": "JavaScript", "til": "uz", "daraja": "orta"},
{"id": 3, "nom": "Go", "til": "en", "daraja": "orta"},
{"id": 4, "nom": "Rust", "til": "en", "daraja": "yuqori"},
]
@app.get("/kurslar")
def kurslar(til: str | None = None, daraja: str | None = None):
natija = KURSLAR
if til:
natija = [k for k in natija if k["til"] == til]
if daraja:
natija = [k for k in natija if k["daraja"] == daraja]
return natija
def main() -> None:
client = TestClient(app)
print("=== 1. Filtrsiz (barchasi) ===")
print(f" /kurslar → {len(client.get('/kurslar').json())} kurs")
print("\n=== 2. Bitta filtr ===")
print(f" ?til=uz → {[k['nom'] for k in client.get('/kurslar?til=uz').json()]}")
print(f" ?daraja=orta → {[k['nom'] for k in client.get('/kurslar?daraja=orta').json()]}")
print("\n=== 3. Kombinatsiyalangan filtr ===")
javob = client.get("/kurslar?til=en&daraja=orta")
print(f" ?til=en&daraja=orta → {[k['nom'] for k in javob.json()]}")
print("\n=== 4. Ixtiyoriy (None) mantig'i ===")
print(" til=None → filtr qo'llanmaydi (barcha til)")
print(" til='uz' → faqat o'zbek tilidagi")
print(" ⭐ ixtiyoriy parametr (None) — filtrni yoqish/o'chirish")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Filtrsiz (barchasi) ===
/kurslar → 4 kurs
=== 2. Bitta filtr ===
?til=uz → ['Python', 'JavaScript']
?daraja=orta → ['JavaScript', 'Go']
=== 3. Kombinatsiyalangan filtr ===
?til=en&daraja=orta → ['Go']
=== 4. Ixtiyoriy (None) mantig'i ===
til=None → filtr qo'llanmaydi (barcha til)
til='uz' → faqat o'zbek tilidagi
⭐ ixtiyoriy parametr (None) — filtrni yoqish/o'chirishNima ko'rsatdi: 2.3, 2.7-bo'limlar.
Misol 4 — Amaliy: filtrlash, saralash, sahifalash
To'liq kurslar API sini barcha parametr turlari bilan yaratamiz: yo'l parametri (bitta kurs), so'rov parametrlari (filtr, saralash, sahifalash) va validatsiya. Bu — real API'ning to'plam endpointi: filtrlanadigan, saralanadigan, sahifalanadigan.
"""to'liq to'plam endpointi: filtr (til), saralash (sort, order), sahifalash (sahifa, hajm) validatsiya bilan; yo'l parametri (bitta kurs); 404."""
import warnings
warnings.filterwarnings("ignore")
from typing import Annotated
from fastapi import FastAPI, HTTPException, Path, Query
from fastapi.testclient import TestClient
app = FastAPI(title="Wisar Kurslar API")
KURSLAR = [
{"id": 1, "nom": "Python", "til": "uz", "narx": 100},
{"id": 2, "nom": "JavaScript", "til": "uz", "narx": 80},
{"id": 3, "nom": "Go", "til": "en", "narx": 120},
{"id": 4, "nom": "Rust", "til": "en", "narx": 150},
{"id": 5, "nom": "Java", "til": "uz", "narx": 90},
]
@app.get("/kurslar")
def kurslar(
til: str | None = None,
sort: Annotated[str, Query(pattern="^(id|nom|narx)$")] = "id",
order: Annotated[str, Query(pattern="^(asc|desc)$")] = "asc",
sahifa: Annotated[int, Query(ge=1)] = 1,
hajm: Annotated[int, Query(ge=1, le=100)] = 10,
):
natija = [k for k in KURSLAR if not til or k["til"] == til]
natija = sorted(natija, key=lambda k: k[sort] if sort in ("nom", "narx") else k["id"], reverse=(order == "desc"))
boshi = (sahifa - 1) * hajm
return {"jami": len(natija), "sahifa": sahifa, "kurslar": natija[boshi:boshi + hajm]}
@app.get("/kurslar/{kurs_id}")
def bitta_kurs(kurs_id: Annotated[int, Path(ge=1)]):
for k in KURSLAR:
if k["id"] == kurs_id:
return k
raise HTTPException(status_code=404, detail="kurs topilmadi")
def main() -> None:
client = TestClient(app)
print("=== 1. Filtr + sahifalash ===")
javob = client.get("/kurslar?til=uz&hajm=2").json()
print(f" ?til=uz&hajm=2 → jami {javob['jami']}, sahifada {[k['nom'] for k in javob['kurslar']]}")
print("\n=== 2. Saralash ===")
javob = client.get("/kurslar?sort=narx&order=desc").json()
print(f" ?sort=narx&order=desc → {[(k['nom'], k['narx']) for k in javob['kurslar']]}")
print("\n=== 3. Sahifalash ===")
javob = client.get("/kurslar?sahifa=2&hajm=2").json()
print(f" ?sahifa=2&hajm=2 → {[k['nom'] for k in javob['kurslar']]}")
print("\n=== 4. Validatsiya ===")
print(f" ?sort=xato → status {client.get('/kurslar?sort=xato').status_code} (pattern)")
print(f" ?hajm=200 → status {client.get('/kurslar?hajm=200').status_code} (le=100)")
print("\n=== 5. Bitta kurs va 404 ===")
print(f" /kurslar/1 → {client.get('/kurslar/1').json()['nom']}")
print(f" /kurslar/999 → status {client.get('/kurslar/999').status_code}")
print(" ⭐ filtr + saralash + sahifalash + validatsiya = to'liq API")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Filtr + sahifalash ===
?til=uz&hajm=2 → jami 3, sahifada ['Python', 'JavaScript']
=== 2. Saralash ===
?sort=narx&order=desc → [('Rust', 150), ('Go', 120), ('Python', 100), ('Java', 90), ('JavaScript', 80)]
=== 3. Sahifalash ===
?sahifa=2&hajm=2 → ['Go', 'Rust']
=== 4. Validatsiya ===
?sort=xato → status 422 (pattern)
?hajm=200 → status 422 (le=100)
=== 5. Bitta kurs va 404 ===
/kurslar/1 → Python
/kurslar/999 → status 404
⭐ filtr + saralash + sahifalash + validatsiya = to'liq APINima ko'rsatdi: 2.1–2.8-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Barcha parametr yo'lda" | Yo'l — resurs; so'rov — sozlash |
| "Parametrni qo'lda aylantirish" | Tip belgisi avtomatik |
| "Validatsiyani qo'lda" | Query/Path beradi |
| "Standartsiz — ixtiyoriy" | Standartsiz — majburiy |
| "Filtr yo'lda" | Filtr — so'rov parametri |
| "Noto'g'ri kirish server osadi" | Validatsiya → 422 |
| "Parametr tartibini belgilash kerak" | FastAPI avtomatik aniqlaydi |
"Annotated keraksiz" |
Zamonaviy, tavsiya etiladi |
6. Keng tarqalgan xatolar va yechimlari
1. Validatsiyasiz parametr
def sahifala(sahifa: int = 1): # ⚠️ manfiy bo'lishi mumkin
def sahifala(sahifa: Annotated[int, Query(ge=1)] = 1): # ✅2. Filtrni yo'lda
@app.get("/kurslar/til/{til}") # ❌ filtr — parametr
@app.get("/kurslar") # ?til=uz # ✅3. Majburiy filtr
def kurslar(til: str): # ❌ filtr majburiy bo'ldi
def kurslar(til: str | None = None): # ✅ ixtiyoriy4. Turni qo'lda aylantirish
def kurs(kurs_id: str):
kurs_id = int(kurs_id) # ❌ qo'lda
def kurs(kurs_id: int): # ✅ avtomatik5. Cheklovsiz hajm
def kurslar(hajm: int = 10): # ⚠️ 10000 bo'lishi mumkin
def kurslar(hajm: Annotated[int, Query(le=100)] = 10): # ✅6. HTTPException o'rniga oddiy javob
return {"xato": "topilmadi"} # ⚠️ status 200
raise HTTPException(404, "topilmadi") # ✅7. Eski Query sintaksisi
sahifa: int = Query(default=1, ge=1) # eski
sahifa: Annotated[int, Query(ge=1)] = 1 # ✅ zamonaviy7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 20.2-dars (o'tilgan): REST — parametrlar (filtr, sahifalash)
- 20.3-dars (o'tilgan): FastAPI — endpoint asoslari
- 13-qism (o'tilgan):
Annotated, tip belgilari - 20.5-dars: Pydantic — tana (body) validatsiyasi
- 20.6-dars: so'rov va javob — chuqurroq
8. Eng yaxshi amaliyotlar
Yo'l parametrlari — resursni aniqlash; so'rov — sozlash.
Filtr/saralash/sahifalash — so'rov parametrlari (ixtiyoriy).
Query/Pathbilan validatsiya (ge,le,min_length).Annotated[tip, Query(...)]— zamonaviy sintaksis.Ixtiyoriy parametrlar —
str | None = Noneyoki standart.hajmkabi parametrlarni cheklang (le) — server himoyasi.Topilmaganda
HTTPException(404).Tip belgilariga tayaning — aylantirish avtomatik.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # {kurs_id} nima?
2. # ?til=uz nima?
3. # def f(sahifa: int = 1) — majburiymi?
4. # def f(q: str) — majburiymi?
5. # Query(ge=1) nima tekshiradi?
6. # kurs_id: int, '5' → ?
7. # sahifa manfiy bo'lsa (ge=1)?
8. # str | None = None nima?
9. # yo'l va so'rov parametrini kim aniqlaydi?
10. # min_length nima tekshiradi?
11. # Annotated nima uchun?
12. # noto'g'ri parametr status kodi?Javoblar
- Yo'l parametri
- So'rov parametri
- Yo'q (ixtiyoriy, standart 1)
- Ha (standartsiz)
- Son >= 1
5(int, avtomatik)- 422
- Ixtiyoriy parametr (None bo'lishi mumkin)
- FastAPI (yo'lda
{...}bor-yo'qligiga qarab) - Satr minimal uzunligi
- Tur + validatsiyani ajratish (zamonaviy)
- 422
Vazifa 2: Xatolarni tuzating
1. @app.get("/kurslar/til/{til}")
def kurslar(til: str): ... # filtr yo'lda
2. def kurslar(til: str): # filtr majburiy
...
3. def sahifala(sahifa: int = 1): # cheklovsiz
...
4. def kurs(kurs_id: str):
kurs_id = int(kurs_id) # qo'lda aylantirish
5. def kurs(kurs_id: int):
if kurs_id not in KURSLAR:
return {"xato": "yo'q"} # status 200Javoblar
1. @app.get("/kurslar")
def kurslar(til: str | None = None): ... # filtr — parametr
2. def kurslar(til: str | None = None): # ixtiyoriy
3. def sahifala(sahifa: Annotated[int, Query(ge=1, le=100)] = 1):
4. def kurs(kurs_id: int): # avtomatik
5. def kurs(kurs_id: int):
if kurs_id not in KURSLAR:
raise HTTPException(404, "yo'q")Vazifa 3: Filtrlanadigan API
"Mahsulotlar" API:
- Filtrlar: kategoriya, narx oralig'i (
narx_min,narx_max) - Saralash (
sort,order) - Sahifalash validatsiya bilan
TestClientbilan test
Vazifa 4: Validatsiya to'plami
Turli validatsiyali endpointlar:
ge/le(son oralig'i)min_length/max_length(satr)pattern(regex — email, telefon)- Har biri uchun 422 test
Vazifa 5: Yo'l vs so'rov
- Bir endpointda yo'l va so'rov parametrlari
- Ichma-ich yo'l (
/kurslar/{id}/darslar/{dars_id}) - Aralash validatsiya
- FastAPI qanday aniqlashini hujjatlang
Vazifa 6: Sahifalash mantig'i
To'liq sahifalash:
sahifa,hajmvalidatsiya bilan- Jami soni, sahifalar soni
keyingi/oldingisahifa havolalari (HATEOAS)- Chegara holatlari (bo'sh, oxirgi sahifa)
Vazifa 7: O'ylash
FastAPI parametr validatsiyasini deklarativ qiladi: Query(ge=1, le=100) — "nima" ni aytasiz, "qanday tekshirish" ni FastAPI qiladi. Bu imperativ (if sahifa < 1: raise ...) validatsiyadan farq qiladi. Nima uchun deklarativ validatsiya afzal, va bu "nima vs qanday" farqi dasturlashda qayerda uchraydi?
Javob
Qisqa javob: Deklarativ validatsiya afzal, chunki u niyatni (nima kerak) ifodalaydi, mexanizmni (qanday tekshirish) emas — FastAPI qanday tekshirishni biladi. Bu qisqaroq, o'qiladigan, xatosiz va — muhimi — hujjatga avtomatik aylanadi (cheklov /docsda ko'rinadi). Imperativ kod (if/raise) har tekshiruvni qo'lda yozadi, takrorlanadi, hujjatga aylanmaydi. "Nima vs qanday" farqi dasturlashda keng: SQL (deklarativ) vs sikl, regex vs tahlil kodi, konfiguratsiya vs kod.
1. Deklarativ vs imperativ
| Imperativ (qanday) | Deklarativ (nima) |
|---|---|
if sahifa < 1: raise ... |
Query(ge=1) |
| Har tekshiruv qo'lda | Cheklov e'lon qilinadi |
| Takror | Qisqa |
| Hujjatga aylanmaydi | Hujjat avtomatik |
2. Nega deklarativ afzal
| Foyda | Tafsilot |
|---|---|
| Qisqa | Kam kod |
| O'qiladigan | Niyat aniq |
| Hujjat | Cheklov ko'rinadi |
| Xatosiz | Framework tekshiradi |
| Izchil | Bir xil format |
3. "Nima vs qanday" boshqa joyda
| Deklarativ (nima) | Imperativ (qanday) |
|---|---|
SQL (SELECT ... WHERE) |
Sikl bilan filtr |
| Regex (naqsh) | Tahlil kodi |
| Query(ge=1) | if/raise |
| Konfiguratsiya | Kod |
| HTML/CSS | Chizish kodi |
4. Deklarativ kuchi
Deklarativ kod nima kerakligini aytadi, tizim qanday qilishni hal qiladi. Bu:
- Optimizatsiya tizimga qoladi
- Kod niyatga yaqin
- Ko'p natija (validatsiya + hujjat)
5. Muhandislik saboqlari
- Niyatni ifodala (nima), mexanizmni yashir (qanday)
- Deklarativ — qisqa, o'qiladigan, hujjatga aylanadi
- Framework mexanizmni biladi
- "Nima vs qanday" — dasturlashning asosiy farqi
6. Xulosa
- Deklarativ validatsiya niyatni ifodalaydi
- FastAPI cheklovni tekshiradi va hujjatlaydi
- Imperativ (if/raise) — takror, hujjatsiz
- "Nima vs qanday" tamoyili keng qo'llaniladi
Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.
Xulosa
Bu darsda route parametrlarini — yo'l va so'rov parametrlarini o'rgandik.
Eng muhim uch fikr:
Yo'l va so'rov parametrlari — turli maqsad. Yo'l parametrlari (
{kurs_id}) resursni aniqlaydi (/kurslar/5— 5-kurs), majburiy (yo'lning bir qismi). So'rov parametrlari (?til=uz&sahifa=2) to'plamni sozlaydi (filtr, saralash, sahifalash), ko'pincha ixtiyoriy (standart qiymatli). FastAPI qaysi parametr yo'lda, qaysi so'rovda ekanini avtomatik aniqlaydi va tip belgisiga qarab aylantiradi.Ixtiyoriy/majburiy va validatsiya. Standart qiymatsiz parametr — majburiy (berilmasa
422); standart qiymatli yokistr | None = None— ixtiyoriy.QueryvaPathqo'shimcha validatsiya beradi:ge/le(son oralig'i),min_length/max_length(satr),pattern(regex). Zamonaviy sintaksis —Annotated[tip, Query(...)] = standart. Validatsiya buzilsa422(server osilmaydi) va cheklovlar hujjatda avtomatik ko'rinadi.To'liq to'plam endpointi. Real API to'plam endpointi filtr (so'rov parametri), saralash (
sort,order—patternbilan cheklangan), sahifalash (sahifa,hajm—ge/lebilan) ni birlashtiradi.hajmkabi parametrlarni cheklash (le=100) — server himoyasi. FastAPI validatsiyasi deklarativ — "nima kerak" ni aytasiz (Query(ge=1)), "qanday tekshirish" ni FastAPI qiladi, va cheklov avtomatik hujjatga aylanadi.
Keyingi darsda Pydantic modellari ni o'rganamiz: so'rov tanasini (body) — murakkab JSON ma'lumotni — model bilan qabul qilish, validatsiya va seriyalizatsiya.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!