12.1 Front-end un back-end arhitektūra
Stundas uzdevums: Saprast, kā mūsdienu lietotnes ir sadalītas priekšgalā un aizmugurē, un ka starp tām notiek HTTP komunikācija.
70 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~15 min) - izseko īstam HTTP pieprasījumam · 2. uzdevums (~25 min) - uzzīmē savas lietotnes arhitektūru · 3. uzdevums (~20 min) - sadali funkcijas starp priekšgalu un aizmuguri. Papildu uzdevumu sāc tikai tad, ja pārējie trīs ir gatavi.
Pirms sāc: atver pārlūku un projekta README.md failu. Šajā stundā kodu vēl nerakstīsi - vispirms jāsaprot, kura koda daļa strādā pārlūkā un kura uz servera.
Teorija: Klients-serveris arhitektūra
Mūsdienu web lietotnes sastāv no divām atšķirīgām daļām:
- Priekšgals (frontend) - tas, ko redz lietotājs pārlūkprogrammā: HTML, CSS, JavaScript.
- Aizmugure (backend) - serveris, kas glabā datus un izpilda biznesa loģiku: Python (Flask/Django), Node.js u.c.
# Komunikācija notiek caur HTTP pieprasījumiem
[Pārlūks] ── GET /api/speletaji ──> [Serveris]
[Pārlūks] <── 200 OK + JSON ──────── [Serveris]
│
▼
[Datubāze]
Galvenās priekšrocības atdalītā arhitektūrai:
- Vairāki klienti (web, mobilais, IoT) var izmantot vienu un to pašu serveri.
- Komandas var strādāt paralēli - frontend un backend izstrādātāji.
- Vienkāršāk testēt, atjaunināt un mērogot katru daļu atsevišķi.
Praktiskie uzdevumi
1. uzdevums -
Izseko īstam HTTP pieprasījumam
Beigās tu savām acīm redzēsi pieprasījumu un atbildi.
- Atver jebkuru mājaslapu un nospied
F12. - Izvēlies cilni Network un pārlādē lapu ar
F5. - Uzklikšķini uz pirmā ieraksta sarakstā.
- Pieraksti, kāda ir metode (GET vai POST) un statusa kods.
- Atrodi sadaļu Response un pieraksti, kāda tipa saturs atnāca.
- Atrodi vienu ierakstu ar statusa kodu, kas nav 200, un pieraksti to.
Gatavs, kad: README.md failā ir pierakstīta viena metode, viens statusa kods 200 un viens cits statusa kods.
2. uzdevums -
Uzzīmē savas lietotnes arhitektūru
Beigās tev būs shēma, kas rāda, kur dzīvo katra daļa.
- Uzzīmē trīs kastes:
Pārlūks,Serveris,Datubāze. - Novelc bultu no pārlūka uz serveri un uzraksti uz tās
GET /api/rezultati. - Novelc atpakaļbultu un uzraksti uz tās
200 + JSON. - Novelc bultu no servera uz datubāzi un atpakaļ.
- Pieraksti katrā kastē, kādā valodā tā kods ir rakstīts.
- Atzīmē, kura kaste atrodas lietotāja datorā.
Gatavs, kad: shēmā ir trīs kastes, četras bultas ar uzrakstiem, un tu vari parādīt, kura daļa strādā lietotāja datorā.
3. uzdevums -
Sadali funkcijas starp priekšgalu un aizmuguri
Beigās tu zināsi, kur katra funkcija jāraksta.
- Uzraksti sarakstu ar sešām savas spēles funkcijām.
- Atzīmē katrai
F(priekšgals) vaiB(aizmugure). - Atzīmē ar
Bvisu, kas glabā datus vai pārbauda uzvaru. - Pieraksti, kāpēc uzvaras pārbaudi nedrīkst atstāt tikai pārlūkā.
- Atrodi vienu funkciju, kas vajadzīga abās pusēs.
- Pieraksti, kāda būtu problēma, ja parole tiktu pārbaudīta pārlūkā.
- Pieraksti vienu secinājumu: kāpēc aizmugurei nekad nedrīkst uzticēties priekšgala datiem.
Gatavs, kad: visas datu glabāšanas un uzvaras pārbaudes funkcijas ir atzīmētas ar B, un tu vari pamatot kāpēc.
Papildu uzdevums - Salīdzini statusa kodus
Ja pamatdarbs ir gatavs, uzzini, ko serveris ar tiem pasaka.
- Uzraksti, ko nozīmē kodi 200, 201, 400, 404 un 500.
- Atrodi pārlūkā vienu lapu, kas atgriež 404.
- Pieraksti, kura no šīm kļūdām ir lietotāja vaina.
- Pieraksti, kura ir servera vaina.
- Pieraksti, kuru kodu atgriezīsi, kad kāds izveidos jaunu rezultātu.
Gatavs, kad: tu vari pateikt, ka 400 ir lietotāja kļūda, 500 - servera, bet 201 nozīmē 'izveidots'.
Biežākās kļūdas
- Sajaukts frontend ar UI: UI ir lietotāja saskarne; frontend ir kods, kas to īsteno.
- API ≠ datubāze: API ir interfeiss, datubāze ir datu krātuve. API var izmantot dažādas datubāzes.
- Aizmirsts CORS: Frontend uz cita domēna nevar piekļūt API bez CORS galvenēm.
Koda piemērs
# Vienkāršs aprakts: kas notiek, kad lietotājs nospiež "Sūtīt"
# 1. FRONTEND (browser)
# fetch("/api/saglabat", { method: "POST", body: ... })
# 2. BACKEND (Python serveris)
@app.route("/api/saglabat", methods=["POST"])
def saglabat():
dati = request.json
# 3. DATUBĀZE
cur.execute("INSERT INTO ... VALUES (%s)", (dati["x"],))
conn.commit()
# 4. ATPAKAĻ FRONTEND
return jsonify({"status": "ok"}), 201
Atbilde: { status: 'ok' }
Kods: 201