Jaxer aneb pokročilý JavaScript na straně serveru

Společnost Aptana vydala nedávno Jaxer 1.0, ostrou verzi svého „ajaxového serveru“. Základem je zdrojový kód Firefoxu 3 s doplněným rozhraním k databázím a souborovému systému. To umožňuje psát aplikace v JavaScriptu i na straně serveru, zbavit se přeskakování mezi jazyky a opakovaně využít část zdrojového kódu na obou stranách (např. validace). Přestože to není jediný pokus o server-side JavaScript, pravděpodobně patří k těm nejvíc životaschopným.
Jaxer je vytvořen jako modul pro webový server Apache a vydán pod licencí GPL. Tím, že je založen na jádru Firefoxu, získáváme na serveru i pokročilý JavaScript (označovaný jako verze 1.8). Jaxer přidává serverové API pro databáze, soubory, logování, procesy, e-mail, síťovou komunikaci a pomocné funkce.
V případě, že to bude vývojář potřebovat, může na straně serveru dokonce provádět manipulaci s DOM a používat známé knihovny Prototype, Scriptaculous, jQuery, Dojo, ExtJS apod. Já si však myslím, že to je spíš nouzové řešení, protože by spotřebovávalo zbytečně mnoho zdrojů na serveru. Proto se používání těchto knihoven na serveru vyhýbám.

AJAX jako prosté zavolání funkce
Vlajkovou lodí Jaxeru je jeho schopnost umístit vybrané funkce na server a přímo je volat z klientské strany. Jaxer se sám postará o komunikaci a serializaci. Funkce, které mají být umístěny na serveru a volány z klienta, stačí vložit do skriptu s atributem runat="server-proxy"
.
V následujícím příkladu je tímto způsobem definována funkce item
, která vrátí jednoduchý objekt odvozený z argumentu. V praxi by zde proběhl např. dotaz do databáze.
<script runat='server-proxy'>
function item(id){
return {
recordId: id,
moneyAmount: id * 100
};
}
</script>
Pro využití dat ze serverové funkce vytvoříme na klientské straně funkci show, která zobrazí odpověď na webové stránce. Funkci přidáme parametr response, do níž nám Jaxer umístí objekt vrácený serverovou funkcí.
function show(response) {
document.getElementById('asynchro').innerHTML += response.moneyAmount;
}
Nyní už zbývá jenom asynchronně zavolat z klienta serverovou funkci. K tomuto účelu pro nás Jaxer vytvořil na klientovi proxy funkci, kterou nazval stejně jako její serverový protějšek – item. My na ní zavoláme metodu async. Jako první argument jí předáme funkci pro obsluhu odpovědi (funkce show). Jako ostatní argumenty jí předáme hodnoty, které chceme předat serverové funkci (v našem případě jenom id, např. číslo 5):
item.async(show, 5);
Jaxer teď zavolá funkci item a jako argument jí předá číslo pět. Funkce item toto číslo převezme, vytvoří podle něho objekt ( {recordId: 5, moneyAmount: 500}
) a vrátí ho. Funkce show dostane tento objekt jako svůj parametr (response) a zobrazí na stránce jeho peněžní částku response.moneyAmount
.
To je všechno, co jsme museli udělat pro případ asynchronního zavolání funkce. Pokud by nám stačilo zavolat serverovou funkci z klienta synchronně, byl by celý postup ještě jednodušší – pouhé zavolání funkce:
response = item(7);
document.getElementById('synchro').innerHTML += response.moneyAmount;
Prohlédnout si můžete kompletní zdrojový kód tohoto příkladu (asynchronní i synchronní verze) včetně podoby HTML dokumentu, který Jaxer zašle klientovi.
Kategorie dostupnosti zdrojového kódu
Dostupnost zdrojového kódu lze v Jaxeru detailně řídit atributem runat
skriptu. Tento atribut může nabývat hodnot:
- server
- server-proxy
- server-nocache
- both
- both-proxy
- both-nocache
- client
Skript samotný může být přímo vložený do HTML stránky nebo být uvedený jako externí soubor.
Případ server-proxy jsme viděli v ukázce. Taková funkce běží na serveru a lze ji volat pomocí proxy funkce z klienta. Nelze ji volat přímo na klientovi. Na klientovi ani není dostupný její zdrojový kód. To je důležité z bezpečnostních důvodů, takto označíme např. funkce pro přihlášení, u kterých nechceme zbytečně poskytovat vodítka pro napadení serveru.
Hodnota server znamená, že funkce bude dostupná pouze na serveru, a to při základním zpracování stránky i v době callbacků (AJAXu) na tuto HTML stránku (tj. serverová funkce volaná z klienta přes proxy bude schopna na serveru zavolat tuto naši „čistě serverovou“ funkci).
Hodnota server-nocache znamená, že funkce bude dostupná pouze na serveru a nebude na ní vytvořena proxy funkce. Navíc bude dostupná pouze při základním zpracování HTML stránky, nikoliv v době callbacků.
Hodnota both, both-proxy a both-nocache přidává k server variantě schopnost běžet přímo na klientovi. Hodnota client (nebo vynechání atributu runat) znamená, že uvedený zdrojový kód poběží pouze na klientovi (klasický klientský JavaScript).
K dispozici je ještě atribut autoload, který umožňuje automaticky načíst serverový skript pro fázi callbacků. V tomto případě budou k dispozici funkce onoho skriptu a navíc bude vykonán jakýkoliv jeho javascriptový zdrojový kód.
Závěr
Z hlediska zkušeností lze říct, že v Jaxeru v současnosti vyvíjím jednu aplikaci a mám ji v docela pokročilém stadiu. Jaxer mi připadá ze všech server-side javascriptů nejživotaschopnější.
Zdroje
- Portál – lze doporučit jako výchozí stránku pro zkoumání Jaxeru.
- Průvodce – obsahuje vhodné materiály pro detailnější studium.
- Referenční příručka
- Diskusní fóra – zde lze hledat další informace a případně položit dotazy.
- Instalační soubory – lze stahovat instalační soubory pro Linux, Windows i Apple.

Seriál Do hlubin implementací JavaScriptu
Pokud se o JavaScript zajímáte, nepřehlédněte náš seriál, který vás provede jeho jednotlivými implementace a srozumitelně vám vysvětlí problematiku fungování jazyka JavaScript.
- Do hlubin implementací JavaScriptu: 1. díl – úvod
- Do hlubin implementací JavaScriptu: 2. díl – dynamičnost a výkon
- Do hlubin implementací JavaScriptu: 3. díl – výkonnostně nepříjemné konstrukce
- Do hlubin implementací JavaScriptu: 4. díl – implementace v prohlížečích
- Do hlubin implementací JavaScriptu: 5. díl – implementace mimo prohlížeče
- SquirrelFish: reprezentace hodnot JavaScriptu a virtuální stroj
- SquirrelFish: optimalizace vykonávání instrukcí a nativní kód
- SquirrelFish: regulární výrazy, vlastnosti objektů a budoucnost
- SpiderMonkey: zpracování JavaScriptu ve Firefoxu
- SpiderMonkey: rychlá kompilace JavaScriptu do nativního kódu
- V8: JavaScript uvnitř Google Chrome
- Rhino: na rozhraní JavaScriptu a Javy
- Velký test rychlosti JavaScriptu v prohlížečích
Jak je to s vykonosti takto napsane aplikace?
Jak je to s se schopnosti vyporadat se s mnoha requesty zaroven?
Ma nejakou podporu pro konverzace, kratsi nez session, ale delsi nez request?
Man toto prostredi nejakou podporu pro rozlozeni pres vice Nodu (server se sklada fyzicky z vice stroju)?
Existuje nejaka podpora pro volani nativnih funkci systemu (napr. kdybych to chtel propojit s OO pro prevod doc do pdf)?
P.S.: Bude tohle mit pokracovani?
Výkonnost je podle jejich testů mezi php a rails. JavaScript na serveru se zkompiluje a pak opakovaně používá. Se zlepšující se rychlostí javascriptu v prohlížečích se to bude dál zlepšovat.
Podpora pro více fyzických strojů tam je. A existuje tam JaxerManager, který podle potřeby spouští a vypíná jednotlivé jaxery (obsluhující požadavky). Jestli jde volat nativní funkce nevím, je možno zpracovat místo html souboru např. php soubor.
Konverzace kratší než session ale delší než request – té otázce moc nerozumím.
Pokračování asi napíšu, jak budou přibývat zkušenosti.
Ještě k těm nativním funkcím systému, možná Process (http://aptana.com/jaxer/guide/develop_processes.html), příp. Sandbox (http://aptana.com/jaxer/guide/develop_sandbox.html)
Tipicky se ve webovych aplikacich objevuji casti do kterych kdyz uzivatel vstoupi pouziva se pro jim aktivovane akce kontext teto casti.
napr. uzivatel vstoupi do diskuse a chce, pak klikne na tlacitko edit a chce editovat tuto konkretni diskusi.
Pristupy jak to udelat sou v zasade 3.
1) ulozime pri vstupu do diskuse prave aktualni diskusi do session a pak vsechny akce berou id diskuse ze session – obrovska nevyhoda, ze uzivatel nemuze byt ve vice nez jedne diskusi zaroven (ale i tak se tento pristup pouziva)
2) Ke kazdemu tlacitku pridame bud hidden field nebo URL parameter diskussionId = idDiskuse a do kazdeho requestu prenasime informaci o diskusi kterou chceme aktci ovlivnit
3) Pri vstupu do diskuse zalozime konverzaci do ktere ulozime identifikator diskuse. Tento objekt ulozime na session a pak predavame na tlacitka identifikator kontextu, nebo identifikator kontextu pridame do cesty ke strance.
1) konverzace ma delku session a muze byt jenom jedna na session
2) konverzace ma delku requestu a pri zakladani nove se inicializuje parametry prenesenymi z predchoziho requestu (coz muze vest k predavani strasne spousty ruznych parmaetru obzvlast kdyz mezi dve stranky vlozime nejakou novou pro nejaky predvyber)
3) konverzace ma delku delsi nez request ale kratsi nez session. Mezi requesty se prenasi identifikator konverzace a ta si drzi vsechny parametry v sobe.
Jak je to s podporou ES 4? Sice přesně nevím, co všechno zahrnuje JS 1.8, ale zajímalo by mě, jestli jde/půjde používat namespace, třídy, určení typu atd.
A bohužel se mi zdá, že životaschopnost tohoto řešení začíná a končí u problému "sehnat hosting", protože přestože ES 4 je už velice schopný jazyk, tak pak stejně člověk řeší "kde pro mou aplikaci sehnat místo", a protože jak na potvoru "cena vždycky hraje roli", bude to faktor, který toto řešení zřejmě pošle k ledu. I když je to skutečně škoda.
ES4 jmenné prostory a nejspíš ani typy mít nebude. Ale hlavně ho ještě pár let neuvidíme, viz http://www.root.cz/clanky/spor-o-budoucnost-javascriptu-vyresen/
Zrovna jsi vyjmenoval věci, které se tvůrci JavaScriptu rozhodli (byli donuceni) vyřadit (kvůli Microsoftu). Ale mně tohle zrovna moc nevadí. Na JavaScriptu se mi líbí ta flexibilnost. V 90. letech udělali jazyk, který se od té doby nezměnil (ve smyslu, že IE blokuje/blokovalo novinky), a přesto se na tom dělají pořád nové formáty jako JSON, knihovny a úpravy, funkce se jednoduše předává jako argument (žádné ukazatele na funkce, delegáty apod.) a tak by se dalo pokračovat ještě hodně dlouho. Třídy a hromady klestí okolo jsem stejně vždy nesnášel.
Hosting už určitě někde na světě existuje, i když samozřejmě nesrovnatelně s PHP. Ale lze si udělat virtuální server u poskytovatele. A Aptana se snaží prosadit svůj Cloud (http://aptana.com/cloud).
Hned na zaciatku napisem ze cim viac sa zacina javascript presadzovat a aj vyskytovat na miestach kde doteraz nebol tym viac ho nemusim a myslim si ze je to slepa cesta.
K Jaxeru.Mna by skor zaujimala stranka bezpecnosti.Vzhladom na to ze javascript bezi na strane klienta (teraz mam na mysli cast ktora vyvola request na server) neni problem si zistit nazvy funkcii (aj ked bude dany script obfusknuty) a potom v pohode volat zaujimave funkcie na servery (myslim niekto cudzi,tretia strana).Ak XSS je na beznych strankach nebezpecny tak na jaxerackom serveri/stranke to bude peklo.Jedine kde by som sa odvazil jaxer nasadit tak to je as intranet.
Na straně klienta běží pouze proxy funkce (vytvořená Jaxerem), takže na klientovi není známé, co je uvnitř té serverové funkce. Z této serverové funkce lze následně volat libovolné jiné funkce, jejich název klient nezná. Je to popsáno ve spodní části článku (Kategorie dostupnosti zdrojového kódu).