OS Web-Apps
in Yesod
WAI/Warp - Router/Handler
Stefan von der Krone
11 MIM
Web Application Interface (WAI)
- Low-Level-Interface zw. Web-Server und Web-App
- Allgemeine Web-Schnittstelle für Haskell
- vgl.
- CGI
- Web Server Gateway Interface (Python)
- Rack (Ruby)
- implementiert von
- Yesod
- Happstack (in Arbeit)
- Hoogle
WAI
- Funktion: Request -> Response
- Lazy IO:
- geringer Speicherverbrauch
- ByteString
WAI
Simples Beispiel:
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types (status200)
import Network.Wai.Handler.Warp (run)
application _ = return $
responseLBS status200 [("Content-Type", "text/plain")] "Hello World"
main = run 3000 application
WAI
Middleware
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.Wai.Handler.Warp (run)
import Network.Wai.Middleware.Gzip (gzip, def)
import Network.HTTP.Types (status200)
application _ = return $
responseLBS status200 [("Content-Type", "text/plain")] "Hello World"
main = run 3000 $ gzip def application
Warp
- Web-Server für Yesod
- implementiert WAI
- extrem schnell
Warp-Benchmark
Mit Vorsicht zu betrachten!!!

Warp-Benchmark
Mit Vorsicht zu betrachten!!!

Warp
Beispiel-App:
app req = return $ case pathInfo req of ["yay"] -> yay -- url-bestandteile ohne query-string x -> index x -- evtl. 404
yay = ResponseBuilder status200 ...
index x = ResponseBuilder status200 ...
Deploy Yesod
Beispiel für nginx
...
server { listen 80; server_name www.myserver.com; location / { proxy_pass http://127.0.0.1:3000; } }
...
Routes
- ermöglicht durch eigene DSL
- TemplateHaskell
- Prinzip:
/ HomeR METHOD
/route RouteR METHOD METHOD
/route/#routeVar RouteVarR METHOD
/route/*routeVars RouteVarsR METHOD
/static StaticR Static getStatic
Routes
- jede Route wird durch eine Resource repräsentiert
- jede Route benötigt einen Handler
- muss explizit geschrieben werden
- es gibt keinen default-Handler
Handler
- bestimmen das Verhalten für die Routen
- werden per TemplateHaskell automatisch erzeugt
/route RouteR METHOD ...
-- wird zu
methodRoute :: Handler Html
Handler
- HTTP sieht GET, POST, DELETE uvm. vor
- Yesod prüft den Methoden-Namen nicht
- eigene Methoden möglich, z.B:
- DOWNLOAD
- STREAM
- Yesod ruft automatisch passende Handler auf
Handler-Beispiele
GET:
-- route
/route RouteR GET
-- handler
getRoute :: Handler -> Html
POST:
-- route
/route RouteR POST
-- handler
postRoute :: Handler -> Text
Keine Methode:
-- route
/route RouteR
-- handler
handleRoute :: Handler -> Html
Path-Piece(s)
- einzelne Bestandteile der URL
- relevant für dynamische URLs
- dynamic single
- dynamic multi
Path-Piece(s)
Single Path-Piece:
-- route
/route/#URLType RouteR METHOD
-- PathPiece methods
instance PathPiece URLType where
toPathPiece (URLType t) = toPathPiece t
fromPathPiece p = do
t <- fromPathPiece p
return $ URLType t
fromPathPiece _ = Nothing -- nicht immer erforderlich, evtl. 404?
Path-Piece(s)
Single Path-Piece:
instance PathPiece Bool where
toPathPiece b = toPathPiece (if b then 1 else 0 :: Int)
fromPathPiece p = do
x <- fromPathPiece p
case x :: Int of
0 -> return False
1 -> return True
_ -> Nothing
Path-Piece(s)
Multiple Path-Pieces:
-- route
/route/*URLType RouteR METHOD
-- PathMultiPiece methods
instance PathMultiPiece URLType where
toPathMultiPiece (URLType t1 t2) = [toPathPiece t1, toPathPiece t2]
fromPathMultiPiece [p1,p2] = do
t1 <- fromPathPiece p1
t2 <- fromPathPiece p2
return $ URLType t1 t2
fromPathMultiPiece _ = Nothing -- evtl. 404?
Path-Piece(s)
Multiple Path-Pieces:
- evtl. müssen noch zusätzliche Single-PathPiece-Methoden für eigene Datentypen implementiert werden
Binary-Yesod-App
-
Beispiel-App
- Umwandeln von binären Zahlen in natürliche
- und andersrum
Binary-Yesod-App
Daten-Typen:
data Natural = Natural Integer deriving (Eq, Show, Read)
data Binary = Binary String deriving (Eq, Show, Read)
Binary-Yedod-App
Der Binary-Datentyp:
toBinary :: Natural -> Binary
toBinary n = Binary $ getBinary $ fromNatural n where
getBinary i = showIntAtBase 2 intToDigit i ""
fromBinary :: Binary -> String
fromBinary (Binary b) = b
Binary-Yesod-App
Der Natural-Datentyp:
toNatural :: Binary -> Natural
toNatural b = Natural $ bin2dec $ fromBinary b where
bin2dec = foldr (\c s -> s * 2 + c) 0 . reverse . map c2i where
c2i '0' = 0
c2i '1' = 1
c2i _ = error "no binary"
fromNatural :: Natural -> Integer
fromNatural (Natural n) = n
Binary-Yesod-App
And Action...
Quellen
- www.yesodweb.com
- hackage
- haskell-wiki
- detailliert im Git-Repo
OS Yesod - WAI/Warp & Router/Handler
By Stefan Von Der Krone
OS Yesod - WAI/Warp & Router/Handler
- 623