NoSQL mění pohled na psaní webových aplikací

Nedávno jsem pracoval na jistém projektu, kde jsem právě použil NoSQL řešení. Na co byste mě tipli? Dělal jsem další Twittery, Facebooky, Googly? Vůbec mi nešlo o výkon. Zaprvé jsem chtěl v praxi NoSQL vyzkoušet, prostě si s tím pohrát (a to byl asi nejsilnější důvod) a zadruhé potřeba vypisovat heterogenní data. Jedná se o jakýsi redakční systém, má jisté kategorie a ve výpisech kategorií jsou samozřejmě články, ale také odkazy na dokumenty, fotky a mohou přibýt i další věci. Relačně se to samozřejmě řešit dá, hned několika způsoby, avšak ani jeden se mi nelíbil, resp. pod vlivem NoSQL opojení jsem nad nimi ani moc neuvažoval a rovnou se vrhl na řešení založeném na nerelačním modelu dat.

Zrovna jsem si přečetl, jak FriendFeed používá MySQL k uskladnění schémaprostých (schema-free) dat, a tak jsem neváhal a vydal se popisovanou cestou. Jedna tabulka v MySQL funguje jako velká mapa klíč-hodnota. Avšak nepoužil jsem další tabulky pro „indexy“, ne, udělal jsem to stylem map-reduce viewy (popravdě řečeno jenom map, reduce fázi jsem /zatím/ neimplementoval, jelikož jsem ji na nic /zatím/ nepotřeboval) jako jsou v CouchDB.

Při stavení webu jsem začínal právě od implementace tohoto úložiště. Když bylo, zjistil jsem, že to člověka donutí znovu popřemýšlet o architektuře aplikace jako celku – takovou moc má model dat databáze! Jasně, člověk si řekne: „Udělám to eMVéCéčkem, né. Akorát naroubuju jú-er-ájka na akcičky kontrolérů a mám vystaráno, redakční systém jak vyšitý!“ Jenže relační model je znače odlišný od modelu dat dokumentově-orientované databáze. Jeden zjistí, že hodně věcí, které by jinak byly buďto napevno zadrátovány v kódu, nebo ještě uloženy někde jinde ve zdrojích aplikace, jsou adepty pro to se stát daty v databázi a ono to u dokumentově-orientované databáze jde jednoduše je tam uložit!

A tak jsem aplikaci oprostil routingu populárního v MV* frameworcích. Místo toho se URI (bez query stringu) testuje vůči URI dokumentu v databázi, lépe řečeno každý dokument může (ale nemusí) mít atribut, tehdy jsem ho nazval _slug, jež určuje relativní cestu vůči rootu aplikace, a je vytvořen view, který mapuje všechny dokumenty se _slugy a na který se potom aplikace dotazuje, když dorazí požadavek. Dokumentem získaným dotazem na view je inicializován objekt (třída objektu je určena atributem _type) a tomu je posléze předáno zpracování požadavku.

A k čemu je to dobré? Takovýmto způsobem můžete jednoduše znovupoužívat komponenty aplikace. Vytvořím si typ Vypis, který bude inicializován dokumentem, ve kterém bude název view pro vypsání, nadpis stránky apod. Vypis ze všech položek view udělá objekty (opět podle jejich _type) a ty na stránce vypíše. Chci vypsat články? Vytvořím view sbírající všechny články, bude se jmenovat VsechnyClanky, a dokument:

{    "_slug":"/clanky",    "_type":"Vypis",    "view": "VsechnyClanky",    "title":"Všechny články"}

A mám výpis článků. Podobně je to s jakýmkoli výpisem, i heterogenním (články, fotky, dokumenty, všechno to dohromady).

Nejlepší na tom je, že takové komponenty aplikace mohou být velice obecné, a tudíž jednoduše znovupoužitelné.

Použití NoSQL databáze může radikálně změnit váš pohled na vývoj aplikací. Doposud jsem si myslel, že část aplikace zpracovávající uživatelů požadavek nelze udělat polymorfně. Ono by to šlo udělat i s relační databází, i s využitím ORM, avšak nikdy jsem neviděl, že by který z frameworků pro PHP, či Ruby, či cokoli jiného polymorfismus kontrolérů, chtete-li prezenterů, podporoval, ba ani že by se o něm zmiňoval v nějakém článku anebo videu.