Ak Vás zaujala časť 1, tak určite Vás zaujme aj táto časť 2. V tejto časti sa pozrieme na spracovanie dynamického obsahu a na uploadovanie súborov.
Trasovanie (routing) považujem asi za najdôležitejšiu časť frameworku, pretože registrovaním (vytvorením) trasy vzniká webová aplikácia. Total.js pozná 3x rôzne typy trás:
F.route()
, príklad: /products/
F.file()
, príklad: /img/logo.png
F.websocket()
príklad: /chat/
Framework vyhodnocuje trasovanie pre každý typ requestu trošku inak. Pri prijatí requestu vyhodnotí framework, či sa jedná o súbor (kontroluje či má .extension
- koncovku) a ak platí, že sa jedná o súbor, tak request ďalej spracúva tzv. FileHandler - (spracovanie statických súborov), v opačnom prípade sa request začne analyzovať ako dynamický obsah:
flags
napr. xhr
, mobile
, robot
, post
, put
, atď.Content-Type
, či request obsahuje binárne dataTento typ requestu je spracovaný najrýchlejšie, pretože neobsahuje žiadne data v tele requestu, ktoré je potrebné dodatočne parsovať. Takže framework vyhodnotí:
Pri zistení, že sa jedná o tento typ requestu, tak framework vyhľadá trasu route
a podľa jej nastavenia začne načúvať udalosť request.on('data')
. Ak trasa neexistuje, framework vracia 403
a žiadne data nepríjma.
Ak trasa existuje tak do dočasnej premennej req.buffer_data
začne framework postupne zapisovať prijaté data po chunk
(rozumej pole bytes
), veľkosť prijatých dát (default: 5 kB) závisí od povolenia v metóde F.route()
(túto veľkosť je možné zmeniť celoplošne aj v configu). Ako náhle veľkosť prekročí stanovený limit:
req.buffer_data
pre vyčistenie pamäti431: Request Header Fields Too Large
V prípade, že data sú OK, tak sa vyhodnocuje:
JSON to Object
, UrlEncoded to Object
, Xml to Object
alebo ostávajú raw
)Uploadovanie súborov je v Total.js dosť špecifické kvôli 2 veciam (o tom neskôr). Na spracovanie uploadu používam algoritmus node-formidable, ktorý používa ak sa nemýlim aj framework Express.js. V každom prípade, nejdem písať o tom ako funguje tento algoritmus, ale ako Total.js rieši problémy s uploadovaním súborov a čo všetko k tomu ešte navyše ponúka.
Upload súborov funguje tak, že všetky súbory v requeste sa automaticky ukladajú do temporary adresára /myapp/tmp/
. Framework pri zisťovaní obsahu requestu a zistení, že sa jedná o súbor otvorí Writable Stream
pre každý súbor a prijaté data po chunk
(rozumej pole bytes
) zapisuje do súboru. Celý tento proces je streamovaný a neblokuje vlákno. V prípade, že sa jedná o obrázok, tak framework sa snaží na základe content-type
súboru zistiť jeho rozmery v prvom chunk
. Pri gif
, png
a svg
je rýchlo čitateľné rozlíšenie obrázku, no a pri jpg
je ten proces trošku náročnejší. Takže prvou špecifickou vecou v Total.js je to, že Total.js Vám pri uploade obrázkov ihneď zistí ich rozlíšenie (toto správanie sa dá vypnúť cez tzv. Total.js behaviour
). Ostatné data (nie binárne) sú spracované klasicky ako pri content-type application/x-www-form-urlencoded
.
Druhou špecifickou vecou pri uploade súborov je to, že Total.js počíta veľkosť aktuálne zapísaných dát, takže sa nemôže stať, že Vám niekto začne uploadovať 1 GB data a tým zaťažovať server. By default je veľkosť nastavená na 5 kB
a pri každej F.route()
si viete túto veľkosť zmeniť:
Po dokončení príjmania dát sa:
UrlEncoded to Object
)Framework vymaže všetky nahraté súbory automaticky, keď sa ukončí response
. Toto správanie sa dá tiež vypnúť cez controller.noClear(true)
, len potom je potrebné vymazať data manuálne cez controller.clear()
alebo req.clear()
.
O WebSocket budem písať v inom blogu, ktorý sa mu bude samostatne venovať. Len pre informovanosť uvediem, že spracovanie WebSocketu funguje trošku inak.
Query argumenty:
req.query
/ controller.query
vlastnosť je parsovaná len vtedy, keď sa volá. Výsledky parsera sú následne uložené do skrytej property a pri opätovnom volaní sa už hodnoty znova neparsujú.
Vyhodnotenie trás je cacheované:
Vyhodnotenie trás a ich flagov sa cachuje. To znamená, že framework sa snaží zapamätať zapamätateľné trasy, tak - aby pri nasledujúcom requeste nemusel prehľadávať všetky trasy znova.
CORS:
CORS mechanizmus sa vyhodnocuje ihneď v prípade OPTIONS
metódy a ďalej framework vo vyhodnocovaní nepokračuje. Napísal som ho tak, aby bol čo najefektívnejší. Framework obsahuje F.cors()
metódu na povolenie CORS, viac v dokumentácii.
Flagy robot
a referer
:
Sú analyzované len vtedy, ak framework obsahuje reálne routes
s týmito flagmi. ... aj takto som sa snažil šetriť performance.
Timeouty:
Zaujímavou funkciou v Total.js sú timeouty. Pokiaľ controller neodpovie v požadovanom čase, napr. stane sa neočakávaná chyba, framework jednoducho request ukončí. Toto správanie sa dá vypnúť alebo upraviť jeho čas priamo pri vytváraní trasy F.route()
. Viac info v dokumentácii.
Dynamicky definované argumenty:
Dynamicky definované argumenty v trasovaní sa nevyhodnocujú nijako špeciálne. Framework vidí dynamické hodnoty takto /products/{0}/{1}/{2}/
a my ich deklarujeme napr. takto /products/{category}/{subcategory}/{detail}/
takže v konečnom dôsledku ich v akcii môžeme nazvať ako chceme, viď nižšie uvedený príklad: