Až Vám zčerná obrazovka, přejděte na Linux!

Proč používat Linux

středa 30. července 2008

Jak oRESTovat Javí aplikaci

Dneska ráno jsem našel naprosto zajímavý článek, první ze série o RESTu, který objasňuje REST na příkladu jeho převedení do světa Javy.

První díl vzali autoři z trošku jiného konce - začali od Bindingu neboli vazby mezi klientem a serverem. Vazbu v RESTu definují jako asociaci logického jména na něco "fyzického", třeba kusu kódu, kus paměti či metodu.

Dávají do kontrastu vazbu mezi jménem třídy v Javě (a klasický ClassLoading) proti volné asociaci mezi URLčkem a "stránkou" Webu. Zasmál jsem se nad přirovnáním, že změna implementace třídy (v jejich příkladě java.util.Date) znamená (bez šíleného overheadu s vlastní implementací ClassLoaderu) restart celého JVM, což v případě Webu je věc naprosto komická. No schválně si představte restart celého Webu. Ten synchronizační komunikační protokol bych chtěl vidět... tedy nechtěl...

Takže si řekli, že:
1. Browser se zeptá Domain Name Service (DNS) na "tapikuv.blogspot.com" (v jejich případě www.theserverside.com, ale co bychom si to neupravili, že :-D) a zpět získá IP adresu.
2. Browser vytvoří TCP/IP spojení na onu IP adresu na portu 80.
3. Spojení použije na odeslání HTTP GET requestu na zdroj "/" na tapikuv.blogspot.com.
4. Server dostane HTTP request, něco s ním udělá a vrátí nějakou reprezentaci zdroje "/".
5. Browser ji dostane, něco s ní provede a zobrazí to uživateli.
6. nakonec browser shodí TCP/IP spsojení a "un-binds" (poměrně hodně podstatné slovo, viz níže) od endpointu.

Takže si kluci zavedli vlastní URI schéma "resource" (např. resource:/customers) a navrhli pár tříd:
1. Context (něco mezi JNDI kontextem a proxy)
2. Request (obdoba HTTP requestu)
3. Representaion (obecná třída, ve své podstatě obdoba java.lang.Object)

Celý proces pak probíhá tak, že na kontextu vytvoří request na konkrétní URI, přidají k němu co potřebují, nechají jej provést a zpět dostanou Representation.

Na první pohled nic nového pod sluncem, máme EJB sdílející s klientem jenom mezixicht (miluji toto slovo, které jsem před víc než 20 lety našel ve VTMku), JNDI Context.lookup(), zavolání metody EJBčka a návrat nějaké hodnoty.

Fígl je v tom, že v tomto systému je jenom jeden mezixicht, sdílí jej tedy VŠECHNA EJBčka. To umožňuje dramaticky omezit různá omezení. Klient se tak de jure nestará o evoluci takovýchto EJBček. Stačí mu jenom znát správné URIčko a umět se vypořádat s instancemi Representation.

Sranda je v tom, že výhody tohoto systému nepochopil téměř žádný diskutující. Odvolávky na zahození typovosti v Javě,když ji přece sami autoři používají, že do Javy to vůbec nepatří, že je to přece k ničemu, když ti server vrátí něco, co ty dopředu nevíš, že vrátí, či na to, že to všechno řeší přece CORBA, DCOM a SOAP, jsou velice srandovní. Šlo přece o vysvětlení na příkladu architektonického stylu. Težko přece budeme dělat RESTovou servisu na operátor ++, že...

Na druhou stranu se autoři zapomněli zmínit o jedné podstatné věci, a tou je právě onen "un-bind". Tato operace totiž není v RESTu definována, kde je nahrazena operací "rebind". Chápu, že ona jemná nuance nemusí být pro mnohé čitelná. Hlavní rozdíl je v tom, že ona vazba mezi logickým jménem a "fyzickou" reprezentací má obvykle trvání přesahující jeden request. Teprve když si klient usmyslí, že je načase aktualizovat odkaz, udělá onen "rebind". Kromě kešování bindingu tu navíc máme ještě kešování reprezentací, kdy zase klient rozhoduje, zda je na čase se podívat po aktuální verzi.

No a samozřejmě mám trochu potíž s onou třídou Context. Podle mne je mnohem lepší ji rozdělit na Registry, Repository a Proxy. Registry mi řekne "fyzičtější" odkaz (zde dělám rebind), Repository mi vrátí Proxy (které si kešuji) a na Proxy pak volám requesty. Přijde mi to logičtější a více RESTózní.

2 komentáře:

Makub řekl(a)...

Ten článek mi přijde nesmyslný. Web není robustní systém, jak autoři tvrdí, právě naopak, je plný nefungujících odkazů. A hlavní rozdíl mezi Webem a Javou/softwarem je, že klienty webu jsou myslící lidé, kterým se předkládá zobrazení dat. Ti si s nefungujícím odkazem nebo špatnými daty poradí tak, že jdou hledat jinam nebo dělat něco jiného.

Software takovou možnost nemá. Ekvivalentem webu v software by bylo, že funkce/metoda vrátí data, a volající kód s nimi nic neudělá, jen je zobrazí člověku, ať si je prohlédne. Ale nebylby schopen data dále zpracovat.

Proto mi připadne absurdní mluvit o tom, že by software mohl fungovat podobně jako web. Jde o zcela neporovnatelný způsob fungování. Proto taky zatím veškeré pokusy o semantický web, kdy software bude schopen dělat s obsahem webu něco jiného než ho zobrazit lidem, zcela ztroskotaly.

Oto 'tapik' Buchta řekl(a)...

Ten článek není ale vůbec nesmyslný! IMHO je to nejzajímavější tutorál k RESTu, jaký jsem gdy viděl, a tak ho taky chápu já. Ale máš pravdu, že je nesmysl takto implementovat JVM. Na tom se shodneme.

Co se týká robustnosti, tak není nic robustnějšího než systém HTML stránek. Nebo mi chceš říct, že pádem jedné aplikace se zřítí celá síť, celý web? Takto například chápu robustnost já - nezáleží, kolik je v systému chyb, ale musí jako celek fungovat a poskytovat co největší možnou funkcionalitu. Web není konzistentní, ale to je něco jiného.

Dále. Software má také IMHO možnost jít hledat jinam, když mu nefunguje to, co používá. Od čeho tu máme Brokery a Registry. Sáhnu do UDDI, najdu nejlépe padnoucí servisu, nejede, hledám další, atd... Totéž, co bys dělal na Gůglu, když dostaneš na odkaz 404. Proto s tebou nesouhlasím, že jediným eqivalentem webu je zase jenom nějaký renderer. Vždycky záleží na míře inteligence a schopnostech klienta. Zkus si představit, že bys ke Gůglu posadil
Tomáše Aqinského. Nebo svoji (či něčí jinou) prababičku. V důchodovém věku. Výsledky se tedy liší i mezi lidmi.

Co se týká sémantického webu, tak tam bych se pouštěl na hodně tenký led a spekuloval a to nechci.