Scottyでのstatic fileミドルウェアの使い方

Scotty続き

Webアプリ作り始めたらjqueryやbootstrapのjsやcss、画像ファイルなどのstaticファイルをとりあえず(rewriteやnginxやCDN使うまで)はフレームワークで配信させると思います。

Haskellも他言語のWeb関連ライブラリと同様の構造(WAIというインタフェースライブラリがある)になっていて、ScottyもWAI対応のミドルウェアを使えます。

staticファイルのパスにディパッチして配信してくれるミドルウェアはNetwork.Wai.Middleware.Staticというやつで、以下のように使えます。

{-# LANGUAGE QuasiQuotes, TemplateHaskell, OverloadedStrings #-}

import Web.Scotty

import Data.ByteString.UTF8 as BU
import Data.Text.Lazy.Encoding

import Network.Wai.Middleware.Static

main = scotty 3000 $ do

  middleware $ staticPolicy $ addBase "static" >->
             (contains "/js/" <|> contains "/css/")

  get "/" $ do
    text "ハロー世界"
    setHeader "content-type" "text/html; charset=UTF-8"

staticPolicyという関数にPolicyを与えます。Policyはボトムアップ的に合成していくようになっていて上記の例では/xxx/yyy/zzzへのリクエストを/static/xxx/yyy/zzzにマップしてxxxかyyyがjsかcssだったらローカルのstatic/xxx/yyy/zzzを配信します。

あと余談ですが、レスポンス本体に日本語があると何もしないとなぜか手元のブラウザがShiftJIS判定して文字化けするのでレスポンスヘッダ"content-type"をsetHeaderでちゃんと設定します。getのディスパッチャのところのtext関数がcontent-typeを設定するのでその後ろでsetHeaderするところもハマりポイントです。


という感じで、あとは

かなり遊べる感じになると思います。

セッションcookieや認証周り、がまだ調査中ですがHTML5のlocalstorageとか使ってanonymousユーザ向けのサイトを作るならこれで十分です。

もちろんメインは他のフレームワークを使って特定のパスだけリバプロでScotty使ってもいいし、単に「サイト内サーバ間通信」でHTTP使うのもムフフな感じですね。(個人的には「サイト内のサーバ間通信」はZeroMQ押しですけれども。)