LoginSignup
11
5

More than 3 years have passed since last update.

【Servant】 (1) Wai

Last updated at Posted at 2020-01-11

【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 ()

今回は以上です。

11
5
0

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
  3. You can use dark theme
What you can do with signing up
11
5