Quickstart-Projekt


... [ Programmiersprachen und Sprachsysteme ] ... [ Das Snap Framework ] ... [ << Einleitung ] ... [ Snap >> ] ...

Das Quickstart-Projekt von Snap bietet sich hervorragend für die ersten Gehschritte an. Dieses Projekt ist bereits in Snap enthalten. Um es zu installieren, erstellt man einen Ordner - der Ordnername wird auch initial als Projektname gesetzt - und ruft in diesem folgenden Befehl auf:

1
$ snap init barebones

Um das Projekt zu bauen und zu starten, müssen die beiden folgenden Befehle im Projektordner ausgeführt werden:

1
2
$ cabal install
$ barebones -p 8000

barebones ist unser Projektname bzw. Ordnername. Mit -p 8000 können wir einen Port angeben. Dies ist aber optional, als Default wird 8000 genommen. Es gibt noch weitere Optionen, um Hostname, IP, SSL (TLS), Kompressionsart, Proxy und weitere Dinge anzugeben.


Übersicht

Wir haben im Quickstart-Projekt folgende Ordnerstruktur:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
.
|\
| barebones.cabal
| dist/
| |\
| | build/
| log/
| src/
| |\
| | Main.hs

Unter src liegen die Anwendungsdateien. dist wird beim Aufruf von cabal install erzeugt und enthält u.a. die kompilierten Dateien. In log werden die Loggingdateien hinterlegt. Als Letztes liegt noch barebones.cabal im Root-Verzeichnis des Projekts. Hier werden Informationen über das Projekt, Angaben über src-Ordner und das Main-Modul gemacht. Außerdem werden hier die Dependencies und Aufrufoptionen für den ghc eingetragen. Als weitere Ordner sind noch snaplets und static möglich. Ersteres beherbergt Snaplets , auf die wir noch später eingehen. Zweiteres enthält die statischen Dateien, wie css-Klassen, Javascript-Dateien und Bilder oder Filme, etc.


Code

Gehen wir nun einmal auf den Sourcecode des Projektes ein.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{-# LANGUAGE OverloadedStrings #-}
module Main where

import           Control.Applicative
import           Snap.Core
import           Snap.Util.FileServe
import           Snap.Http.Server

main :: IO ()
main = quickHttpServe site

site :: Snap ()
site =
    ifTop (writeBS "hello world") <|>
    route [ ("foo", writeBS "bar")
          , ("echo/:echoparam", echoHandler)
          ] <|>
    dir "static" (serveDirectory ".")

echoHandler :: Snap ()
echoHandler = do
    param <- getParam "echoparam"
    maybe (writeBS "must specify echo/param in URL")
          writeBS param

Die Funktion quickHttpServe nimmt einen Handler und beginnt HTTP Responses zu liefern. Um diesen Prozess zu beenden, muss der kontrollierende Prozess beendet werden. Der Handler wird in der Funktion site erzeugt. Hier werden verschiedene Methoden aufgezeigt, wie man ein Routing aufbaut. Als Erstes haben wir ifTop, welches eine Aktion bekommt, diese aber nur ausführt, wenn das Root-Verzeichnis der Anwendung angefragt wird. Dieses kann mit dir kombiniert werden, welches eine Anfrage nur ausführt, wenn diese mit einem bestimmten ByteString (hier "static") beginnt. Es wird aber empfohlen das Routing mit route aufzubauen, da dieses ein besseres Laufzeitverhalten besitzt. Die drei Möglichkeiten werden hier mit dem binären Operator <|> verknüpft, welcher zunächst das erste Argument auswertet und, wenn es fehlschlägt, das Ergebnis der zweiten Aktion nimmt. Wir haben hier zudem noch die zwei Funktionen writeBS, welche einen ByteString nimmt und an die Antwort hängt, sowie serveDirectory, welches die Dateien aus einem Ordner statisch zurückgibt. Für Ersteres gibt es noch eine lazy-Variante writeLBS, sowie zwei Varianten mit dem Datentyp Data.Text. Als Letztes haben wir noch getParam. Diese Funktion nimmt einen ByteString und liefert aus dem Request den entsprechenden Paramter. Es gibt auch hier eine zweite Variante, um den Parameter aus dem POST des Requests zu holen getPostParam. Abschließend noch einmal die Funktionsköpfe in der Übersicht.

1
2
3
4
5
6
7
8
quickHttpServe  :: Snap () -> IO ()
ifTop           :: MonadSnap m => m a -> m a
route           :: MonadSnap m => [(ByteString, m a)] -> m a
dir             :: MonadSnap m => ByteString -> m a -> m a
writeBS         :: MonadSnap m => ByteString -> m ()
serveDirectory  :: MonadSnap m => FilePath -> m ()
getParam        :: MonadSnap m => ByteString -> m (Maybe ByteString)
<|> :: f a -> f a -> f a



... [ Programmiersprachen und Sprachsysteme ] ... [ Das Snap Framework ] ... [ << Einleitung ] ... [ Snap >> ] ...
generated by schmidt-doku-generator (GitHub)