Happstack: část první

Webový framework Happstack je postaven na funkcionálním jazyce Haskell. Vývoj webových aplikací pomocí jazyka deklarativního paradigmatu je pro běžného vývojáře něčím těžko představitelným. V tomto miniseriálu si proto společně ukážeme základní koncepty a naučíme se vytvářet jednoduché aplikace.

Seriál: Happstack: Webový framework v Haskellu (3 díly)

  1. Happstack: část první 19.5.2010
  2. Happstack: část druhá 26.5.2010
  3. Happstack: část třetí 2.6.2010

Většina webových aplikací je napsána v nějakém z imperativních jazyků. Nezáleží na tom, zda-li se jedná o PHP, Javu, či cokoliv jiného, tyto jazyky fungují na principu vykonávání sekvence příkazů (imperativů). Kód takového jazyka se tak podobá receptu: přiřaď tuhle hodnotu sem, pokud se rovná jiné hodnotě, vynásob ji a výsledek ulož tam, jinak udělej něco jiného. Oproti tomu deklarativní jazyky pouze zavádí (deklarují) určitá tvrzení, kterými se překladač při vyhodnocování řídí. Kód funkcionálních jazyků se tak často podobá matematickému předpisu: faktoriál přirozeného čísla většího než nula se rovná násobku faktoriálu čísla o jedno menší, jinak se rovná jedničce.

Současným trendem je přejímání některých funkcionálních prvků do imperativních jazyků, protože mohou výrazně zkrátit a zpřehlednit kód. Možná používáte anonymní funkce v JavaScriptu, generátory seznamů v Pythonu, nebo funkce vyššího řádu v Ruby, aniž byste tušili, že pochází z funkcionálního světa. Proto znalost funkcionálního programování rozhodně není na škodu a může vám pomoci stát se lepším programátorem v konvenčnějších jazycích. Kromě toho existuje nejeden úspěšný webový projekt, jenž byl napsán v nějakém z funkcionálních jazyků, což popisuje kupříkladu Paul Graham ve svém článku Beating the Averages.

Seznamte se, Haskell

Haskell je čistě funkcionální jazyk, který je staticky typovaný, referenčně transparentní a jeho kód se vyhodnocuje líně. Při programování ve frameworku Happstack se bez jeho znalosti neobejdeme. Jako lehký úvod do tohoto jazyka může sloužit seriál Petera Almásyho Haskell a funkcionalní programování, pro bezbolestné pochopení základů doporučuji tutoriál Naučte se Haskell! a praktičtější příklady přináší kniha Real World Haskell, která je k dispozici zdarma online.

Nemáte-li s funkcionálním programováním zatím žádné zkušenosti, nevadí. Nahlédnutí do tohoto seriálu může být užitečné i z hlediska popisu principů, na nichž framework stojí.

Pokud jste, stejně jako já, spíše praktičtěji zaměření, určitě vás bude zajímat, jak je na tom Haskell s rychlostí, stabilitou a rozšířeností. Mnoho zajímavých jazyků je v praxi obtížně nasaditelných, protože nepodávají dostatečný výkon, jejich implementace jsou neúplné či chybové, případně pro ně vůbec neexistuje použitelný překladač pro požadovanou platformu. Haskell prošel již poměrně dlouhým vývojem (jeho počátky sahají do konce osmdesátých let), jeho překladač GHC je stabilní, podporuje nativní překlad jak pro systémy založené na Unixu, tak pro Windows, a výkonnostně je na tom velice dobře (viz např. The Computer Language Benchmarks Game).

Alternativy k Happstacku

Happstack není jediným zástupcem svého druhu. V Haskellu je napsáno několik dalších knihoven pro vývoj webových aplikací. Příkladem může být framework Turbinado, který se v lecčem podobá Ruby on Rails či Djangu, jenže ten byl nedávno opuštěn hlavním vývojářem a tím pádem se přestal vyvíjet. I samotný Happstack měl podobný osud — jeho kód vychází z frameworku HAppS, jenž byl taktéž zanechán svému osudu. Autoři nejspíše psaní frameworku brali jako výzvu a po dotažení do použitelné podoby ztratili zájem o další rozšiřování. Kromě těchto dvou frameworků existuje spousta dalších, jejichž nekompletní seznam lze nalézt, spolu s popisem haskellových webových serverů a dalších užitečných knihoven, na HaskellWiki.

Instalace

Haskell má vlastní instalační systém Cabal. Ten umožňuje jednoduchou instalaci bez nutnosti programy překládat ručně. Ovládá se přes rozhraní Cabal-install. Pro zprovoznění tohoto systému je třeba mít nainstalovaný překladač GHC (nejlépe nejnovější verze) společně s Haskell Platform, což je sada nejčastěji používaných rozšiřujících knihoven Haskellu, mezi nimiž se nachází i Cabal.

Veškerá data instalačního systému se ukládají do adresáře ~/.cabal/. Nachází se tam i adresář bin, který je třeba přidat do proměnné prostředí PATH, kupříkladu připsáním řádku export PATH="$PATH:$HOME/.cabal/bin" na konec souboru  ~/.bashrc.

Jakmile máme Cabal funkční, stačí nám zadat do příkazové řádky tyto příkazy:

$ cabal update
Downloading the latest package list from hackage.haskell.org
$ cabal install happstack
Resolving dependencies...
... 

Příkaz cabal update získá aktuální seznam balíčku z repozitáře Hackage, příkaz cabal install happstack automaticky stáhne a nainstaluje balíček happstack včetně jeho závislostí. Pokud z nějakého důvodu automatická instalace přes Cabal nefunguje, musíme si stáhnout balíčky ručně, rozbalit je, a pomocí této trojice příkazů nakonfigurovat a přeložit:

$ runhaskell Setup configure
$ runhaskell Setup build
$ runhaskell Setup install 

Tento postup je zdlouhavý a nedoporučuje se, protože Happstack závisí na mnoha jiných balíčcích. Ať už jsme nainstalovali modul Happstack jakýmkoliv způsobem, jeho funkčnost ověříme napsáním příkazu  happstack:

$ happstack
Usage: happstack <command>
Possible commands:
  build auto <buildCmd> <binPath> <binArgs>...: invoke the auto-builder
  new project <dir>: create a new happstack project 

Pomocný příkaz happstack slouží k ulehčení zakládání a sestavování projektů Happstacku, což jsou vlastně jenom adresáře s předpřipravenými daty. My si vytvoříme svůj vlastní adresář, kam umístíme svůj první program.

Náš první program

Konvence stanovuje hlavní soubor projektu pojmenovávat jako Main.hs. Do tohoto souboru napíšeme tento jednoduchý kód:

module Main where

import Happstack.Server

main :: IO ()
main = simpleHTTP nullConf $ return "Ahoj světe!"

V kódu importujeme modul Happstack.Server obsahující funkci simpleHTTP, jenž spouští webový server na výchozím portu 8000. První parametr této funkce je konfigurační struktura (datový typ Conf), druhý parametr je samotný aplikační kód (typu ServerPartT IO). Tato ukázka vrací na každý dotaz text Ahoj světe!, a protože je to parametr typu IO, používá funkci return. Happstack se standardně dodává s vlastní implementací webového serveru.

Když soubor uložíme, spustíme v příkazovém řádku příkaz runhaskell Main a zadáme do prohlížeče adresu http://localhos­t:8000/, zobrazí se nám v něm text. Stisknutím klávesové zkratky Ctrl + C můžeme spuštěný server ukončit a program si přeložit do binárního kódu:

$ ghc --make Main
[1 of 1] Compiling Main             ( Main.hs, Main.o )
Linking Main ... 

Vytvoří se nám soubor Main, který spustíme pomocí příkazu ./Main. Pro vývoj a testování je lepší nečekat, než se kód přeloží, ale spouštět si zdrojový kód příkazem runhaskell, kdežto pro nasazení je lepší mít kód již přeložený.

Nasazení pomocí FastCGI

Vestavěný webový server je poměrně rychlý, ale nepoužívá vlákna. Jestliže na náš server míří velké množství HTTP požadavků, jejich obsloužení nemůže probíhat paralelně a tím pádem narůstá doba odezvy. V reálném světě by tedy těžko obstál. Pomocí balíčku happstack-fastcgi máme možnost Happstack propojit s knihovnou FastCGI, která běží pod Apache či pod jiným webovým serverem. Před napsáním příkazu cabal install happstack-fastcgi je nutné nainstalovat vývojové soubory FastCGI (v Debianu se jedná o balíček libfcgi-dev). Poté v našem programu provedeme několik změn:

module Main where

import Happstack.Server
import Happstack.Server.FastCGI

main :: IO ()
main = runFastCGIConcurrent 8 . serverPartToCGI $ return "Ahoj světe!"

Kombinace funkcí runFastCGIConcurrent a serverPartToCGI spustí server s osmi vlákny, přičemž aplikační kód zůstane stejný. Tento program musíme následně přeložit s parametrem pro zapnutí podpory vláken:

$ ghc -threaded --make Main.hs -o main.fcgi
[1 of 1] Compiling Main             ( Main.hs, Main.o )
Linking main.fcgi ... 

Pomocí parametru -o si stanovíme název výsledného binárního kódu. Dále tuto binárku musíme propojit se serverem. Do konfigurace serveru (např. u Apache 2 to je soubor /etc/apache2/httpd.conf) připíšeme tento kód:

<VirtualHost *:80>
  FastCGIExternalServer example.cz/main.fcgi -socket example.cz/main.sock
  RewriteEngine On
  RewriteRule ^/(.*)$ /example.cz/main.fcgi/$1 [QSA,L]

  ServerName example.cz
  ServerAlias www.example.cz
  DocumentRoot /var/www/
</VirtualHost> 

Konfigurace nám zajistí, aby se pro doménu example.cz, která má veškeré soubory uloženy v adresáři /var/www/example.cz/, použil soubor main.fcgi. Přepisování pomocí mod_rewrite nám obstarává „hezká“ URL. Po překopírování naší binárky do tohoto adresáře a restartu serveru (příkaz /etc/init.d/apache2 restart) uvidíme na adrese http://example­.cz/ opět náš text. Tedy za předpokladu, že na náš server směřuje DNS záznam  example.cz.

Související odkazy

Příště si vytvoříme obsáhlejší příklad, který bude zpracovávat data.

Autor je dlouhodobým studentem Fakulty informatiky, webový nadšenec a programátor — nejraději programuje v jazycích Haskell a Python.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 13

Přehled komentářů

Trm ehm, ...
Pavel Dvořák Re: ehm, ...
binary_runner Re: ehm, ...
Pavel Dvořák Re: ehm, ...
stilett Re: ehm, ...
iyo Ubuntu a happstack
Pavel Dvořák Re: Ubuntu a happstack
jirtos proč?
Pavel Dvořák Re: proč?
Radek Miček Re: proč?
Radek Miček Re: Happstack: část první
Pavel Dvořák Re: Happstack: část první
Radek Miček Re: Happstack: část první
Zdroj: https://www.zdrojak.cz/?p=3236