1.ブログの構築
ウェブで紹介されているHaskell web programmingは、簡潔で分かりやすい例題である。その内容に沿って説明し、yesogの活用法を学ぶこととする。
2.エコーで返す
最初の課題は、「/echo/テキストにアクセスしたら、そのテキストを返す」というサービスを開発する。このサービスの名前をEchoとし、サービスを実現してくれるモデル・ビュー・コントローラを作成することとする。まずは、コントローラの作成から始める(なお、このサービスは情報を蓄積しないので、モデルは必要ではない)。
現在のディレクトリがプロジェクトのディレクトリ(この場合にはyosog)にあることを確認して、次のコマンドを入力する。
yesod add-handler
route名、routeのパターン、メソッドのリストが要求されるので、それぞれ、Echo, /echo/#String, GETを入力する。ここで、route名はサービス名、routeのパターンはこのサービスを利用するときのURL(ここでは、~/echo/文字列となる)。メソッドはサービスの機能で、ここでは文字列の入力である。要求を受けたときの応答は次のようになる。
Name of route (without trailing R): Echo Enter route pattern (ex: /entry/#EntryId): /echo/#String Enter space-separated list of methods (ex: GET POST): GET
上記の応答によって以下の作業がなされる
1) config/routeファイルに次の事項が追加される。これらは、URLのパターン、ハンドラーの名前、HTTPのメソッドである。
/echo/#String EchoR GET
2) Handler/Echo.hsのファイルが作成される。
3) Application.hsにimport Handler.Echoが追加される。
4) cabalファイルにHandler.Echoが宣言される。
但し、Handler/Echo.hsのファイルは未完成なので、この部分
getEchoR = error "Not yet implemented: getEchoR"
を、次のように置き換える。これは、入力されたテキストをそのまま表示する。本来はビューで実現される機能だが、取りあえず、コントローラのところで、表示も含めて行うようにする。
getEchoR theText = defaultLayout [whamlet|<h1>#{theText}|]
再びコンパイルして展開する。
cabal install yesod devel
ブラウザからホームページ
localhost:3000/echo/Yesod%20rocks!
にアクセスすると%20がスペースに変換され、Yesod rocks!と出力される。
3.外部からの攻撃に強力
外部から悪意があってこのサービスにアタックしてきたとする。今、文字以外のコードが含まれた次のものでアクセスされたとする。
http://localhost:3000/echo/I’m <script>alert(\”Bad!\”);</script>
この時、ホームページにはnot foundと出力され、このサービスに侵入されることはない。
これは、Haskellが型言語であることが功を奏している。少し詳しく説明すると、次のようになっている。
URL* typeで与えられたサービス要求は、String typeに変換され、さらに、Html typeへと変換される。その様子を示したのが以下である。この変換の過程の中で、String typeに属さないものは拒絶される。上記の例では、scriptを定義している部分がそうである(なお、これはHtml typeではある)。
http://localhost:3000/echo/some%20text%3Ca%3E :: URL “some text<a>” ::String “som text &lt;a&gt;” ::Html
3.おめかしする
プルグラムの内容をもう少し洗練化し、構造化するために、次の2点を追加する。
1) StringからData.Textに型を変える。
2) Handlerの中に記述されているビューの部分をtemplateディレクトリに移す。
1)を実行するために、Foundations.hsに
import Data.Text
を追加する。
config/routesを
/echo/#Text EchoR GET
に変更する。
また、Handler/Echo.hsを
module Handler.Echo where import Import getEchoR :: Text -> Handler Html getEchoR theText = defaultLayout [whamlet|<h1>#{theText}|]
に変更する。
2)を実現するために、ファイルtemplates/echo.hamletを次のように
<h1> #{theText}
と作成する。
先ほど変更したHandler/Echo.hsを、さらに、
module Handler.Echo where import Import getEchoR :: Text -> Handler Html getEchoR theText = defaultLayout $(widgetFile "echo")
に変更する。