Dio 1 – HTTP i REST
Dio 2 – JSON i OpenAPI
Dio 3 – Događaji i vanjski servisi
Praksa – Mali FastAPI server; HTTPie
Materijale priredio Erkan Islamović
erkan.islamovic@eubd.edu.ba · erkan.islamovic@gmail.com
Petnaest sedmica, svaka s tri časa teorije i tri časa prakse. Danas: poglavlje 10 (Sedmica 10, označeno). Isti primjer kroz knjigu: DeliveryApp, narudžba N-1001 (24,50 €).
| Sed. | Poglavlje | Sed. | Poglavlje |
|---|---|---|---|
| 1 | P1 Zašto projektujemo | 9 | P9 Arhitektura |
| 2 | P2 Životni ciklus | 10 | P10 Integracija i API |
| 3 | P3 Zahtjevi | 11 | P11 Korisnički interfejs |
| 4 | P4 Poslovni procesi | 12 | P12 Sigurnost i privatnost |
| 5 | P5 UML i slučajevi korištenja | 13 | P13 Realno vrijeme i IoT |
| 6 | P6 Klase i objekti | 14 | P14 Kvalitet i isporuka |
| 7 | P7 Sekvence i stanja | 15 | P15 AI i završni projekat |
| 8 | P8 Baza podataka |
U decembru 1998. godine NASA je lansirala letjelicu Mars Climate Orbiter, koja je trebala kružiti oko Marsa i proučavati njegovu atmosferu. Na putu, koji je trajao devet mjeseci, letjelica je povremeno palila male motore da ispravi putanju. Podatke o tim paljenjima računao je softver na Zemlji koji je napravila firma Lockheed Martin, a navigaciju je vodio tim NASA-ine laboratorije JPL. Dogovor je bio da se jačina paljenja šalje u njutn-sekundama, metričkoj jedinici. Ali jedan program je slao brojeve u funta-sila sekundama, američkoj jedinici. Jedna funta-sila sekunda je oko 4,45 njutn-sekundi, pa je navigacija svaki put četiri i po puta potcijenila koliko je motor gurnuo letjelicu. Greška se gomilala mjesecima. U septembru 1999. letjelica je prišla Marsu mnogo niže nego što je trebalo i izgubljena je u njegovoj atmosferi. Istražna komisija je kao glavni uzrok navela upravo ovu neusklađenost jedinica između dva programa. Oba programa su, svaki za sebe, „radila”. Pogriješio je dogovor između njih, a taj dogovor danas zovemo interfejs ili API.
U poglavlju 9 nacrtali smo kontejnere DeliveryApp: mobilnu aplikaciju, web aplikaciju restorana, API server, bazu, red poruka i servis obavještenja, uz vanjski sistem plaćanja i servis mapa. Strelice između njih nosile su natpise kao „JSON preko HTTPS”. Ovo poglavlje objašnjava šta te strelice znače i kako se dogovor između dijelova piše tako da se ne desi greška kao s jedinicama na Marsu. Prvo učimo HTTP i REST, jezik kojim aplikacija razgovara sa serverom. Zatim JSON i OpenAPI, kojim se dogovor zapisuje kao ugovor. Na kraju događaje, redove poruka i povezivanje s vanjskim sistemima koji ponekad ne odgovaraju. Na praktičnoj nastavi pokrećemo pravi mali server DeliveryApp u Pythonu i šaljemo mu zahtjeve.
Nakon poglavlja možete:
objasniti šta je API i zašto je dogovor između sistema najosjetljiviji dio integracije; opisati HTTP zahtjev i odgovor; izabrati pravu HTTP metodu i statusni kod; projektovati REST adrese za resurse DeliveryApp; pročitati i napisati JSON za narudžbu, s jasnim jedinicama; pročitati OpenAPI specifikaciju i objasniti zašto se piše prije koda; objasniti verzionisanje i kompatibilnost API-ja; razlikovati sinhronu integraciju, webhook i red poruka; projektovati poziv vanjskog servisa s vremenskim ograničenjem, ponovnim pokušajem i idempotentnim ključem; pokrenuti FastAPI server DeliveryApp i poslati mu zahtjeve iz HTTPie.
| Čas | Sadržaj | Na času |
|---|---|---|
| Teorija 1 | 10.1–10.3 API, HTTP, REST | Šalter s jelovnikom; pet adresa DeliveryApp |
| Teorija 2 | 10.4–10.6 JSON, jedinice, OpenAPI, verzije | Mars 1999: 4,45 puta; ugovor prije koda |
| Teorija 3 | 10.7–10.9 Webhook, događaji, vanjski servisi, sigurnost | Kako se kartica ne naplati dvaput |
| Praksa 1–3 | FastAPI server; HTTPie; /docs; OpenAPI | 201, 422, 409 i 24,50 € |
API (od engleskog application programming interface, programski interfejs aplikacije) je dogovoren način na koji jedan program traži uslugu od drugog. Mobilna aplikacija DeliveryApp ne zna kako server računa dostavu, kako izgleda baza, ni u kojem je jeziku server napisan. Zna samo dogovor: „pošalji ovakav zahtjev na ovu adresu i dobićeš ovakav odgovor”.
Slika iz života: šalter s jelovnikom u restoranu brze hrane. Gost ne ulazi u kuhinju. Na šalteru piše šta se može naručiti, kako (broj menija) i šta se dobija. Kuhinja može promijeniti peć, kuhara ili raspored, a gost i dalje naručuje isto. API je taj šalter: sakriva unutrašnjost i obećava šta se dobija.
To obećanje je ugovor. Ako se jedna strana ne drži ugovora, sistem se kvari, iako je svaki dio sam za sebe ispravan, kao kod letjelice na Marsu. Zato je projektovanje API-ja jedna od najvažnijih arhitektonskih odluka: mobilne aplikacije na hiljadama telefona zavise od njega i ne mogu se sve promijeniti preko noći.
Dijelovi DeliveryApp razgovaraju preko interneta protokolom HTTP (Hypertext Transfer Protocol), istim kojim preglednik otvara web stranice. Protokol je skup pravila razgovora, kao bonton telefonskog poziva. U HTTP-u razgovor je uvijek isti: klijent pošalje zahtjev, server vrati odgovor.
Zahtjev ima četiri dijela:
/v1/narudzbe/N-1001;Odgovor ima statusni kod, zaglavlja i tijelo.
| Metoda | Šta radi | Primjer u DeliveryApp |
|---|---|---|
GET | čita, ne mijenja ništa | pročitaj jelovnik restorana R-1 |
POST | pravi nešto novo | napravi narudžbu |
PATCH | mijenja dio postojećeg | promijeni stanje narudžbe u PRIHVAĆENA |
PUT | zamjenjuje cijelo postojeće | zamijeni cijeli jelovnik |
DELETE | briše | ukloni jelo s jelovnika |
Statusni kod je trocifren broj čija prva cifra kaže grupu: 2xx uspjeh, 4xx greška klijenta (zahtjev nije dobar), 5xx greška servera.
| Kod | Značenje | Kada ga DeliveryApp vraća |
|---|---|---|
| 200 OK | uspjeh | jelovnik je pročitan, cijena izračunata |
| 201 Created | napravljeno | nova narudžba N-1001 |
| 400 Bad Request | zahtjev je pokvaren | tijelo nije ispravan JSON |
| 401 Unauthorized | niste prijavljeni | nema tokena za prijavu |
| 403 Forbidden | prijavljeni ste, ali nemate pravo | kupac pokušava promijeniti stanje narudžbe |
| 404 Not Found | ne postoji | narudžba N-9999 |
| 409 Conflict | sukob sa stanjem | otkazivanje narudžbe u pripremi (PP-6) |
| 422 Unprocessable Content | podaci su čitljivi, ali krše pravilo | adresa 11 km (PP-3), iznos 4,50 € (PP-1) |
| 500 Internal Server Error | greška u našem kodu | izuzetak koji nismo predvidjeli |
| 503 Service Unavailable | server privremeno ne može | preopterećenje ili održavanje |
Dobar API vraća pravi statusni kod i kratku poruku. Loš API na sve vraća 200 i u tijelu piše „greška”, pa aplikacija mora čitati tekst da bi saznala da nešto nije u redu.

Kako izabrati adrese i metode? Najrašireniji stil zove se REST (representational state transfer). Ideja je jednostavna: podaci se vide kao resursi, svaki resurs ima svoju adresu, a radnje su HTTP metode. Adrese su imenice u množini, a ne glagoli.
API DeliveryApp, verzija 1:
| Metoda i adresa | Šta radi | Uspjeh | Greške |
|---|---|---|---|
GET /v1/jela?restoran=R-1 | jela jednog restorana | 200 | – |
POST /v1/cijena | izračunaj cijenu (ne čuva ništa) | 200 | 422 |
POST /v1/narudzbe | napravi narudžbu u stanju NOVA | 201 | 404, 422 |
GET /v1/narudzbe/N-1001 | pročitaj narudžbu | 200 | 404 |
PATCH /v1/narudzbe/N-1001/stanje | promijeni stanje | 200 | 404, 409 |
Primijetite dvije stvari. Prvo, ove adrese su upravo strelice prema serveru iz sekvencijalnog dijagrama (poglavlje 7): izracunaj_cijenu je postala POST /v1/cijena, a napravi_narudzbu je postala POST /v1/narudzbe. Drugo, PATCH …/stanje ne postavlja stanje „na silu”: server poziva promijeni() iz poglavlja 7, i ako prelaz nije u tabeli, vraća 409 Conflict. Tabela prelaza je tako zaštićena i na nivou API-ja.
Mobilna mreža je nepouzdana. Kupac pritisne „Naruči”, zahtjev ode, ali odgovor se izgubi u tunelu. Aplikacija ne zna je li narudžba napravljena, pa pošalje zahtjev ponovo. Hoće li kupac dobiti dvije narudžbe i dvije naplate?
Ovdje pomaže pojam idempotentnosti: zahtjev je idempotentan ako ponavljanje ima isti efekat kao jedan zahtjev. GET je idempotentan (čitanje dvaput ništa ne mijenja). PATCH stanje=PRIHVAĆENA je idempotentan u smislu da je narudžba poslije oba poziva prihvaćena. POST /v1/narudzbe nije: svaki poziv pravi novu narudžbu. Kako se to rješava, vidjećemo u 10.8.
Odgovori: tipka R ili klik na zamućeno polje.
Podaci u zahtjevu i odgovoru najčešće se šalju u formatu JSON (JavaScript Object Notation, čita se „džejson”). JSON je običan tekst s malo pravila: objekat je u vitičastim zagradama i ima parove "ime": vrijednost; niz je u uglastim zagradama; vrijednosti su tekst (pod navodnicima), broj, true/false ili null.
Zahtjev za cijenu N-1001:
{
"kupac": "K-01",
"udaljenost_km": 4.2,
"stavke": [
{"jelo_id": 1, "kolicina": 2},
{"jelo_id": 3, "kolicina": 1}
]
}Odgovor servera:
{
"artikli": 2150,
"popust": 0,
"dostava": 300,
"ukupno": 2450,
"valuta": "EUR",
"jedinica": "cent"
}U JSON-u se, kao u svakom kodu, piše decimalna tačka (4.2). A sada najvažnija lekcija ovog poglavlja, ona s Marsa: broj bez jedinice je opasan. Šta znači "dostava": 300? Tri stotine eura? Tri eura? Zato dobar API jedinicu stavlja u ime polja (udaljenost_km) ili u odgovor ("jedinica": "cent"), i obavezno u ugovor (10.5).
Ista pravila važe za druge vrste podataka koje se često pokvare između sistema:
| Podatak | Opasnost | Dogovor DeliveryApp |
|---|---|---|
| novac | eur ili centi? decimalni zarez ili tačka? | cijeli broj centi, polje valuta |
| udaljenost | km ili milje? | km, u imenu polja |
| vrijeme | koja vremenska zona? 03/04 je mart ili april? | ISO 8601 u UTC: 2026-10-02T10:10:00Z |
| tekst | kodiranje slova č, ć, ž | UTF-8 |
| stanje | „Prihvacena”, „prihvaćena”, „ACCEPTED”? | tačno jedna od sedam vrijednosti iz poglavlja 7 |
Komisija za Mars Climate Orbiter zaključila je 1999. da se greška u jedinicama mogla otkriti, ali da provjere interfejsa između dva programa nisu bile dovoljne. Pouka za svakog projektanta: u ugovoru između sistema svaki broj ima jedinicu, a test provjerava i jedinicu, ne samo da je broj stigao.
Ugovor API-ja može se opisati riječima u dokumentu, ali tada ga ljudi i programi čitaju različito. Zato postoji standard OpenAPI: opis API-ja u formatu YAML ili JSON koji kaže, za svaku adresu, koje metode postoje, šta se šalje, šta se vraća i koje greške su moguće. Dio ugovora DeliveryApp (cijeli fajl je primjeri/deliveryapp/openapi.yaml):
openapi: 3.1.0
info:
title: DeliveryApp API
version: 1.0.0
paths:
/v1/cijena:
post:
summary: Izračunaj cijenu narudžbe (ništa se ne čuva)
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/NarudzbaUlaz"
responses:
"200":
description: Obračun po pravilima PP-1 do PP-5
"422":
description: Narudžba krši PP-1 ili PP-3 (premala ili izvan zone)
components:
schemas:
NarudzbaUlaz:
type: object
required: [kupac, udaljenost_km, stavke]
properties:
udaljenost_km: { type: number, description: "udaljenost u kilometrima", example: 4.2 }
stavke:
type: array
minItems: 1YAML je format sličan JSON-u, ali bez zagrada: uvlačenje redova pokazuje šta je unutar čega. Ovaj opis čitaju i ljudi i programi:
/docs);Pristup u kojem se ugovor napiše i dogovori prije pisanja koda zove se API-first (prvo API). Tim mobilne aplikacije i tim servera tada mogu raditi istovremeno: obje strane znaju ugovor, a mobilni tim do završetka servera koristi lažni server koji vraća primjere iz ugovora. To je upravo ono što je nedostajalo kod Healthcare.gova (poglavlje 1), gdje su dijelovi različitih firmi zajedno isprobani tek na kraju.
Kad je API jednom objavljen, na njega se oslanjaju aplikacije na hiljadama telefona, i to i one stare, koje kupci mjesecima ne ažuriraju. Zato se API mijenja pažljivo.
Promjene se dijele na dvije vrste:
Za nekompatibilne promjene pravi se nova verzija: /v2/narudzbe, dok /v1/ radi dalje neko vrijeme, uz najavu kada će biti ugašena. Zato adrese DeliveryApp od početka počinju sa /v1/.
„Samo ćemo preimenovati ukupno u ukupno_centi, to je sitnica.” Za server jeste. Za svaku staru aplikaciju koja traži polje ukupno, cijena je odjednom prazna, pa kupac vidi „0,00 €” ili aplikacija padne. Sitna promjena u ugovoru nije sitna za one koji ga se drže.
Odgovori: tipka R ili klik na zamućeno polje.
Dijelovi sistema razgovaraju na tri osnovna načina, a dobar projektant za svaku strelicu bira pravi:
POST na našu adresu /v1/placanja/potvrda. Ne moramo ga pitati svakih pet sekundi „je li plaćeno?”.Slika iz života: sinhroni poziv je telefonski razgovor, webhook je „nazvaću vas kad bude gotovo” u servisu za auto, a red poruka je oglasna tabla u hodniku: objavite obavještenje, a svako ko prođe pročita ga kad stigne.
| Strelica u DeliveryApp | Način | Zašto |
|---|---|---|
| aplikacija → server: cijena | sinhrono | kupac mora vidjeti cijenu odmah |
| server → servis mapa: udaljenost | sinhrono | bez udaljenosti nema cijene |
| sistem plaćanja → server: potvrda | webhook | banka odgovara za nekoliko sekundi; ne čekamo |
| server → servis obavještenja: „spremna” | događaj u redu | obavještenje ne smije usporiti restoran |
| server → izvještaji: „isporučena” | događaj u redu | izvještaj se računa kasnije, svojim tempom |

Vanjski sistemi (servis mapa, sistem plaćanja) nisu pod našom kontrolom. Nekad kasne, nekad ne odgovore, nekad odgovore dvaput. Dobra integracija to očekuje i ima tri alata.
1. Vremensko ograničenje (timeout). Nikad se ne čeka zauvijek. Specifikacija UC-01 kaže: ako servis mapa ne odgovori za 10 sekundi, kupac vidi poruku i ne može platiti (alternativni tok 3a, poglavlje 5). Bez ograničenja, jedan spor vanjski servis zauzme sve niti servera i DeliveryApp prestane odgovarati svima.
2. Ponovni pokušaj s pauzom (retry with backoff). Mnoge greške su prolazne: mreža je na trenutak pala. Zato se poziv ponovi, ali ne odmah i ne beskonačno: npr. poslije 1 s, pa 2 s, pa 4 s (pauza se svaki put udvostruči), najviše tri puta. Zbir čekanja je tada 1 + 2 + 4 = 7 sekundi. Udvostručavanje sprečava da hiljade klijenata u istom trenutku zatrpa servis koji se tek oporavlja.
3. Idempotentni ključ. Ponovni pokušaj je opasan za plaćanje. Ako je prvi zahtjev „naplati 24,50 €” stigao do banke, a samo se odgovor izgubio, drugi pokušaj bi naplatio još jednom. Rješenje: uz svaki zahtjev za naplatu šalje se jedinstven idempotentni ključ (npr. N-1001-placanje-1). Sistem plaćanja pamti ključeve: ako stigne isti ključ drugi put, ne naplaćuje ponovo, nego vrati rezultat prvog pokušaja. Isti trik štiti i POST /v1/narudzbe od duple narudžbe iz 10.3: aplikacija šalje ključ, a server s istim ključem ne pravi drugu narudžbu.
Slika iz života za idempotentni ključ: broj na računu u restoranu. Ako konobar dvaput donese isti račun broj 4711, platite jednom, jer je to isti račun.
Ako vanjski servis stalno pada, nema smisla svaki zahtjev slati ponovo. Obrazac prekidač kola (circuit breaker) poslije nekoliko uzastopnih grešaka „isključi” poziv na neko vrijeme i odmah vraća grešku ili rezervni odgovor (npr. „dostava će biti obračunata pri preuzimanju”), a zatim povremeno proba da li se servis oporavio. Ime dolazi od osigurača u kući, koji iskoči da ne bi izgorjela instalacija.
API je vrata sistema, pa ga moraju čuvati brave. Detaljno o sigurnosti govori poglavlje 12, a za API su najvažnije četiri stvari:
Authorization). Server iz tokena zna ko je i koju ulogu ima.Odgovori: tipka R ili klik na zamućeno polje.
Cilj je pokrenuti pravi API server DeliveryApp u Pythonu, poslati mu zahtjeve iz HTTPie i preglednika, pročitati automatsku OpenAPI dokumentaciju i proširiti API jednom adresom. Radi se u folderu kod/.
kod/:pip install fastapi uvicorn httpieapi.py i openapi.yaml iz primjeri/deliveryapp/ (uz deliveryapp.py koji već imate).uvicorn api:app --reloadhttp://127.0.0.1:8000/docs. FastAPI je sam napravio dokumentaciju iz koda, po standardu OpenAPI. Otvorite POST /v1/cijena, kliknite Try it out i pošaljite primjer.U drugom terminalu pošaljite (HTTPie sam pretvara ime=vrijednost u JSON; := znači broj ili JSON, a ne tekst):
http GET :8000/v1/jela restoran==R-1
http POST :8000/v1/cijena kupac=K-01 udaljenost_km:=4.2 stavke:='[{"jelo_id":1,"kolicina":2},{"jelo_id":3,"kolicina":1}]'Očekivani odgovor drugog zahtjeva:
HTTP/1.1 200 OK
{
"artikli": 2150,
"dostava": 300,
"jedinica": "cent",
"popust": 0,
"ukupno": 2450,
"valuta": "EUR"
}POST :8000/v1/narudzbe. Očekivano: 201 Created i "broj": "N-1001", "stanje": "NOVA".http PATCH :8000/v1/narudzbe/N-1001/stanje stanje=PRIHVAĆENA
http PATCH :8000/v1/narudzbe/N-1001/stanje stanje=U_PRIPREMI
http PATCH :8000/v1/narudzbe/N-1001/stanje stanje=OTKAZANAPrva dva vraćaju 200. Treći vraća 409 Conflict s porukom nedozvoljen prelaz U_PRIPREMI -> OTKAZANA: pravilo PP-6 čuva API.
http GET :8000/v1/narudzbe/N-1001) i pogledajte polje istorija.Pošaljite i zapišite statusni kod i poruku za: narudžbu na 11 km; narudžbu s jednom voćnom salatom (4,50 €); stavku s količinom 0; nepostojeće jelo 99; narudžbu N-9999. Uporedite s tabelom statusnih kodova iz 10.2: koji kod biste vi izabrali za svaki slučaj, i da li se slaže s onim što server vraća?
Dodajte u api.py adresu GET /v1/narudzbe?kupac=K-01 koja vraća sve narudžbe jednog kupca. Zatim dopišite istu adresu u openapi.yaml. Provjerite u /docs da se pojavila i pošaljite joj zahtjev iz HTTPie. Razmislite: je li ova promjena kompatibilna s verzijom v1? (Jeste: nova adresa ne ruši stare klijente.)
Dajte AI asistentu svoj openapi.yaml i zatražite: „Pronađi polja bez jedinice ili opisa, i greške koje API ne opisuje.” Svaku primjedbu provjerite i ispravite u ugovoru. Zatražite i HTTPie naredbe za sve greške iz koraka 4, pa ih pokrenite i provjerite da AI nije pogodio pogrešan statusni kod.
Rezultat koji se predaje: kod/api.py s novom adresom, dopunjen kod/openapi.yaml, i fajl kod/zahtjevi.md s naredbama iz koraka 2 do 5 i stvarnim odgovorima servera (statusni kodovi i tijela).
Rješenja su sakrivena – tipka R ili klik na okvir.
Za svaku radnju napišite metodu, adresu i statusni kod uspjeha: a) restoran označi Capricciosu kao nedostupnu; b) kupac pročita svoju narudžbu N-1002; c) administrator doda restoran R-4; d) restoran ukloni jelo 6 s jelovnika.
a) PATCH /v1/jela/2 s tijelom {"dostupno": false}, 200. b) GET /v1/narudzbe/N-1002, 200. c) POST /v1/restorani, 201. d) DELETE /v1/jela/6, 204 (No Content) ili 200.
Koji kod treba vratiti? a) kupac nije poslao token; b) kupac K-02 pokušava pročitati N-1001 kupca K-01; c) tijelo zahtjeva nije ispravan JSON; d) restoran pokušava prihvatiti već isporučenu narudžbu; e) baza je pala.
a) 401; b) 403 (ili 404, ako ne želimo otkriti da narudžba postoji); c) 400; d) 409, jer prelaz ISPORUČENA → PRIHVAĆENA nije dozvoljen; e) 503 (ili 500).
Napišite JSON odgovor servera na GET /v1/narudzbe/N-1002 (4 × Ćevapi, 2,5 km, stanje NA_PUTU, dostavljač D-3), s jedinicama u imenima polja ili posebnim poljem.
Na primjer:
{
"broj": "N-1002",
"kupac": "K-02",
"restoran": "R-2",
"stanje": "NA_PUTU",
"dostavljac": "D-3",
"udaljenost_km": 2.5,
"artikli": 3200,
"dostava": 0,
"ukupno": 3200,
"valuta": "EUR",
"jedinica": "cent",
"vrijeme": "2026-10-02T10:25:00Z"
}Koje promjene API-ja v1 su kompatibilne? a) dodano polje procijenjeno_vrijeme_min u odgovor narudžbe; b) polje ukupno sada je u eurima s decimalama (24.5) umjesto u centima; c) nova adresa GET /v1/restorani; d) polje kod u zahtjevu postaje obavezno; e) stanje NA_PUTU preimenovano u U_DOSTAVI.
Kompatibilne: a) i c). Nekompatibilne: b) (promjena tipa i značenja: stara aplikacija bi prikazala 0,24 €), d) (stari klijenti ne šalju kod, pa bi dobili grešku), e) (stari klijenti ne prepoznaju novo stanje). Za b, d i e treba verzija v2.
Servis mapa ne odgovara. DeliveryApp čeka najviše 2 sekunde po pokušaju i ponavlja najviše tri puta, s pauzama 0,5 s, 1 s i 2 s između pokušaja. Koliko najduže kupac čeka dok ne vidi poruku o grešci? Da li to poštuje alternativni tok 3a (10 sekundi)?
Četiri pokušaja (prvi i tri ponovna) po najviše 2 s = 8 s, plus pauze 0,5 + 1 + 2 = 3,5 s, ukupno 11,5 s. To je više od 10 sekundi, pa ne poštuje tok 3a; treba smanjiti broj pokušaja ili trajanje čekanja (npr. tri pokušaja po 2 s i pauze 0,5 s i 1 s daju 6 + 1,5 = 7,5 s).