@@ -0,0 +1,111 @@
1+WAI: Web Application Interface
2+==============================
3+
4+Getting started
5+---------------
6+
7+You want a minimal example? Here it is!
8+
9+> {-# LANGUAGE OverloadedStrings #-}
10+> import Network.Wai
11+> import Network.Wai.Enumerator (fromLBS)
12+> import Network.Wai.Handler.SimpleServer (run)
13+>
14+> app :: Application
15+> app _ = return Response
16+> { status = Status200
17+> , responseHeaders = [(ContentType, "text/plain")]
18+> , responseBody = Right $ fromLBS "Hello, Web!"
19+> }
20+>
21+> main :: IO ()
22+> main = do
23+> putStrLn $ "http://localhost:8080/"
24+> run 8080 app
25+
26+Put that code into a file named _hello.hs_ and install [wai] and
27+[wai-extra] from Hackage:
28+
29+ cabal install wai wai-extra
30+
31+Run it:
32+
33+ runhaskell hello.hs
34+
35+Point your browser to:
36+
37+ http://localhost:8080/
38+
39+
40+Serving static content
41+----------------------
42+
43+We can modify our previous example to serve static content. For this
44+create a file named _index.html_:
45+
46+ <p>Hello, Web!</p>
47+
48+Now we redefine `responseBody` to refer to that file:
49+
50+> app2 :: Application
51+> app2 _ = return index
52+>
53+> index = Response
54+> { status = Status200
55+> , responseHeaders = [(ContentType, "text/html")]
56+> , responseBody = Left "index.html"
57+> }
58+
59+
60+Basic dispatching
61+-----------------
62+
63+An `Application` maps `Request`s to `Response`s:
64+
65+ ghci> :info Application
66+ type Application = Request -> IO Response
67+
68+Depending on the path info provided with each `Request` we can serve
69+different `Response`s:
70+
71+> app3 :: Application
72+> app3 request = case pathInfo request of
73+> "/" -> return index
74+> "/raw/" -> return plainIndex
75+> _ -> return notFound
76+>
77+> plainIndex = Response
78+> { status = Status200
79+> , responseHeaders = [(ContentType, "text/plain")]
80+> , responseBody = Left "index.html"
81+> }
82+>
83+> notFound = Response
84+> { status = Status404
85+> , responseHeaders = [(ContentType, "text/plain")]
86+> , responseBody = Right $ fromLBS "404 - Not Found"
87+> }
88+
89+
90+Doing without overloaded strings
91+--------------------------------
92+
93+For the sake of efficiency, WAI uses the [bytestring] package. We used
94+GHCs [overloaded strings] to almost hide this fact. But we can easily do
95+without. What follows is a more verbose definition of `notFound`, that
96+works without GHC extensions:
97+
98+ import qualified Data.ByteString.Char8 as B8
99+ import qualified Data.ByteString.Lazy.Char8 as LB8
100+
101+ notFound = Response
102+ { status = Status404
103+ , responseHeaders = [(ContentType, B8.pack "text/plain")]
104+ , responseBody = Right $ fromLBS $ LB8.pack "404 - Not Found"
105+ }
106+
107+
108+ [wai]: http://hackage.haskell.org/package/wai
109+ [wai-extra]: http://hackage.haskell.org/package/wai-extra
110+ [overloaded strings]: http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#overloaded-strings
111+ [bytestring]: http://hackage.haskell.org/package/bytestring