【Servant】(1) Wai - Qiita
【Servant】(2) Servantチュートリアル - Qiita
【Servant】(3) エンドポイントを増やす - Qiita
【Servant】(4) URLパラメータをハンドラの引数とする - Qiita
【Servant】(5) JSON - Qiita
【Servant】(6) HTML - Qiita
【Servant】(7) Post Data - Qiita
【Servant】(8) Another Monad - Qiita
【Servant】(9) Handlerモナド - Qiita
【Servant】(10) SQLite - Qiita
【Servant】(11) Servant-Client - Qiita
【Servant】(12) Basic 認証 - Qiita
Web Application Interface :: Yesod Web Framework Book- Version 1.6
wai: Web Application Interface. - Hackage
ここ数年間、Haskellから遠ざかっていましたけど、「プログラミングHaskell 第2版」をきっかけに、再び戻ってきました。ちょうどstackが出たころに離れたので、stackを使うのは新鮮な感じです。
今回はServentを少し調べてみたいと思います。最初はWaiから始めます。
#1. WAI & Warp
WAI & Warpの説明です。
- WAI: web applications と web servers の間のコミュニケーション・プロトコルを提供するものです。
- Warp: WAIをハンドリングするためのWebサーバです。A fast, light-weight HTTP server
#2. サンプルを動かす
stackでテスト環境を構築します。
stack new wai-test
cd wai-test
wai,warp,http-typesの3つのパッケージを導入するためにpackage.yamlに3行追加します。
dependencies:
- base >= 4.7 && < 5
- wai
- warp
- http-types
Hackageのサンプルを使います。
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
app :: Application
app _ respond = do
putStrLn "I've done some IO here"
respond $ responseLBS
status200
[("Content-Type", "text/plain")]
"Hello, Web!"
main :: IO ()
main = do
putStrLn $ "http://localhost:8080/"
run 8080 app
コンパイルします
stack build
実行します。warpサーバが起動します
stack exec wai-test-exe
curlコマンドでアクセスすると、以下の出力が確認できます。
$ curl http://localhost:8080
Hello, Web!
この時、サーバ側のコンソールには以下のログが出力されます。
I've done some IO here
#3. 型を確認する
それではプログラムの型を確認していきましょう。
Network.Wai - Hackage - Haskell
Application型とresponseLBS型について確認します。
type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
responseLBS :: Status -> ResponseHeaders -> ByteString -> Response
Applicationのコードです。
app :: Application
app _ respond = do
putStrLn "I've done some IO here"
respond $ responseLBS
status200
[("Content-Type", "text/plain")]
"Hello, Web!"
少し詳細に確認します。
- appはIO ResponseReceivedであり、do構文の途中に任意のIO文を挿入できます。
- appの第1引数はRequest型ですが、_ とある通り無視されています。
- appの第2引数はrespond::(Response -> IO ResponseReceived) です。
- respondはresponseLBSでbuildされたResponseを引数として、IO ResponseReceived型の値を返します。
responseLBSはResponse composersと呼ばれ、その他にもresponseFileやresponseStreamなどがあります。
次にWAIをハンドリングするlight-weight HTTP serverであるwarp(run)の型を確認します。
Network.Wai.Handler.Warp - Hackage - Haskell
type Port = Int
run :: Port -> Application -> IO ()
今回は以上です。