search
LoginSignup
5

More than 1 year has passed since last update.

posted at

updated at

【Servant】 (1) Wai

【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行追加します。

package.yaml
dependencies:
- base >= 4.7 && < 5
- wai
- warp
- http-types

Hackageのサンプルを使います。

app/Main.hs
{-# 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 ()

今回は以上です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5