09/2017

Haskell-Framework fürs Web Programmieren Exot im Boot Yesod

84 Das Yesod-Framework setzt neben den gängigen Webtechnologien wie HTML, Javascript und CSS auf einen

Haskell-Compiler. Dieser optimiert aggressiv und überprüft jede Funktion auf ihre Korrektheit. Angela Minosi www.linux-magazin.de

nenten für schnelle Erfolge sorgt und die immer noch steile Lernkurve ein wenig abflacht. Der Artikel hilft bei den ersten Schritten mit Yesod.

Installation

Für die Installation des Framework steht Stack [7] bereit, mit dem der Entwickler darüber hinaus ein Softwareprojekt ein- richtet. Der Vorgang unterscheidet sich von Betriebssystem zu Betriebssystem, der Artikel beschreibt ihn für Fedora 25, das zunächst einige Pakete benötigt, um Stack einsatzfähig zu machen. Um sie zu holen, bindet der Entwickler mit »dnf« (Listing 1) das inoffizielle Repository un-

© Pablo Hidalgo, 123RF Hidalgo, © Pablo ter [8] ein. Um ein neues Yesod-Projekt zu starten, genügt es, den Haskell-Compiler lokal zu Frameworks fürs Web existieren wie nur seine geringere Verbreitung, son- installieren: Sand am Meer, die meisten basieren dern auch die in den Compiler einge- cd auf den Programmiersprachen PHP und baute Sicherheit (Haskell ist typsicher) stack setup Javascript, andere verwenden Python, machen Angriffe teuer bis unmöglich Ruby, Go oder dergleichen. Greift ein und SQL- und Javascript-Injections un- Nach der Installation wartet der Haskell- Entwickler zu Wordpress [1], wahrscheinlich. Zudem verarbeitet der Compiler unter »~/.stack/programs/ [2] oder [3], muss er in der Haskell-Compiler GHC [6], der seit April x86_64‑linux/GHC‑Version/bin«. Zusätz- Regel lediglich den Kern auf dem Server 1990 in Version 1.0 existiert und auf dem liche Pakete, die ein Yesod-Projekt be- entpacken und weitere Module ergän- flotten C-Compiler basiert, Anfragen an nötigt, installiert bei Bedarf ein simples zen. Spielt er gewissenhaft und zeitnah die Webseite deutlich effizienter als viele »stack install Paketname« nach. Sicherheits-Aktualisierungen ein, kommt andere Programmiersprachen. Da Haskell auch die übliche Malware meist auf kei- zu den funktionalen Programmierspra- Homebanking nen grünen Zweig. chen gehört, machen sich auch an ande- Doch es gibt auch durchaus einige ren Stellen Erleichterungen bemerkbar, Ist diese erste Hürde genommen, beginnt Gründe, die für den Einsatz exotischer etwa beim Multithreading. die eigentliche Arbeit. Yesod unterstützt Frameworks wie des auf Haskell [4] Entwickler treibt aber vor allem die diverse bekannte Datenbanken, darunter basierenden Yesod [5] sprechen. Nicht Frage um: Wie klappt der Einstieg in Mongo DB, SQlite und – ansatzweise – das Framework? Denn Haskell gilt als . Der Artikel beschreibt die Integ- Listing 1: Stack auf Fedora 25 schwer zu erlernen, orientiert sich stark ration von PostgreSQL [9] und MySQL

01 dnf install make automake gcc gmp‑devel libffi an der mathematischen Logik und ver- [10]. Der Entwickler erzeugt zunächst wendet viele abstrakte Konzepte wie Mo- ein neues Projekt, indem er den folgen- zlib zlib‑devel xz tar git gnupg dnf‑plugins‑core naden und Category Theory. Hier hilft ein den Befehl eingibt: 02 dnf copr enable petersen/stack Framework wie Yesod, das beim Umstieg 03 dnf install stack auf Haskell dank vorgefertigter Kompo- stack new Projektname yesod‑Datenbank 09/2017 Programmieren Die »Datenbank« ersetzt er durch einen sie im Projektordner, was die Datenbank tei »stack.«. Dabei wählt das Tool gültigen Wert, den er etwa der Tabelle un- sofort einsatzfähig macht. automatisch den neuesten Snapshot des ter [11] entnimmt, also »yesod‑postgres« Haskell-Compilers. Das lässt sich über oder »yesod‑«. den Eintrag neben »resolver:« ändern,

Erstkontakt Yesod Soll die Webanwendung die Daten in eine unter [13] sucht der Entwickler einen MySQL-Datenbank schaufeln, muss diese Die zum Kompilieren des Projekts benö- Snapshot aus. Alternativ gibt er die Ver- zuvor bereits im Hintergrund laufen. Das tigten Pakete schreibt Stack in die Da- sionsnummer eines systemweit installier- bewirken die Schritte aus Listing 2. An- 85 schließend wechselt der Entwickler in Listing 2: MySQL-Datenbank in Betrieb nehmen das von Stack erzeugte Projektverzeich- 01 mysql ‑u root ‑h localhost ‑p nis und bearbeitet die Datei »config/ 02 mysql> CREATE mydb;

settings.yml«. Unterhalb der Überschrift www.linux-magazin.de 03 mysql> CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; »database:« passt er die Einträge für 04 mysql> GRANT ALL PRIVILEGES ON mydb.* TO 'user'@'hostname' IDENTIFIED BY 'password'; den Datenbankbenutzer, den Host und den Namen der Datenbank an, da der Haskell-Compiler das Projekt andernfalls Listing 3: PostgreSQL-Datenbank aufsetzen nicht übersetzt. 01 systemctl start Datenbank

Wer für sein Projekt eine PostgreSQL-Da- 02 psql ‑U postgres ‑c "CREATE EXTENSION adminpack;" tenbank nutzen möchte, startet über die 03 postgres=# CREATE USER 'user' WITH PASSWORD 'password'; Schritte aus Listing 3. Wer keine hohen 04 postgres=# CREATE DATABASE myproject; Ansprüche an die Datenbank stellt, greift 05 postgres=# GRANT ALL PRIVILEGES ON DATABASE myproject TO 'user'; am besten zu SQlite [12], das für nur 06 postgres=# \q einen Benutzer gedacht ist. Yesod erzeugt

Listing 4: »contact.hs«

01 ‑‑ in geschweiften Klammern stehen Quasi Quotes 35  ,contactEmail :: Text 02 {‑# LANGUAGE ViewPatterns #‑} 36  ,contactText :: Textarea 03 {‑# LANGUAGE MultiParamTypeClasses #‑} 37 } deriving Show 04 {‑# LANGUAGE OverloadedStrings #‑} 38 ‑‑ Funktion erzeugt ein Formular vom Typ MForm 05 {‑# LANGUAGE TypeFamilies #‑} 39 createForm :: Html ‑> MForm Handler (FormResult ContactForm, Widget) 06 {‑# LANGUAGE TemplateHaskell, QuasiQuotes #‑} 40 createForm extra = do 07 ‑‑ Bibliotheken importieren 41 ‑‑ mreq = required ‑> Pflichtfeld 08 import Yesod 42  (nameRes,nameView) <‑ mreq textField "Name" Nothing 09 import Data.Text 43  (emailRes,mailView) <‑ mreq emailField "Email" Nothing 10 import Control.Applicative 44  (textRes,textView) <‑ mreq textareaField "Text" Nothing 11 import Yesod.Form 45  let contactRes = ContactForm <$> nameRes <*> emailRes <*> textRes 12 ‑‑ setzt den Port des Webservers Warp auf 3000 46  widget = do 13 main :: IO () 47  toWidget 14 main = warp 3000 FormApp 48 ‑‑ Lucius‑Stylesheet einbinden 15 data FormApp = FormApp 49  [lucius| 16 instance Yesod FormApp 50  @bColor: mediumseagreen; 17 instance RenderMessage FormApp FormMessage where 51  ##{fvId nameView}, ##{fvId mailView}, 18  renderMessage _ _ = defaultFormMessage ##{fvId textView}{ 19 ‑‑ die Webanwendung "FormApp" bringt nur eine Route mit 52  border: 3px solid #{bColor}; 20 mkYesod "FormApp" [parseRoutes| 53  } 21 /contact ContactR GET |] 54  |] 22 ‑‑ eine Hilfsfunktion bindet das Formular widget in eine Webseite ein 55  [whamlet| 23 page enctype widget res = defaultLayout $ do 56  #{extra} 24 ‑‑ Titel der Webseite setzen 57 

Kontaktformular! 25  setTitle "Contact" 26  [whamlet| 58 

Name: ^{fvInput nameView} 27 

Ergebnis: #{show res} 59 

Email: ^{fvInput mailView} 28 

60 

Text: ^{fvInput textView} 29  ^{widget} 61  |] 30