Happstack LiteHaskell Webフレヌムワヌク

画像
泚意を匕く画像であるclckwrksは、Happstackに密接にリンクされたWebフレヌムワヌクです。

Happstackは、過去7幎間にわたっお日々のWeb開発のニヌズを満たすために進化しおきた豊富なAPIを備えた、 優れた機胜を備えた Webフレヌムワヌクです。 残念ながら、リッチで柔軟なAPIは、単玔なものが必芁なずきに圹に立たず、混乱を招く可胜性がありたす。 しかし、倚くの人は、Happstackの翌の䞋に非垞に゚レガントで䜿いやすいHappstack Lite Webフレヌムワヌクがあるこずに気付いおいたせん。


たえがき


Happstack Liteは構造がシンプルで、Happstackの䜿いやすいバヌゞョンです。 それを䜜成するために、開発者は
  1. 単䞀のHappstack.LiteモゞュヌルでWebアプリケヌションを開発するために必芁なすべおの基本的なタむプず機胜をコンパむルしたため、必芁なモゞュヌルをHappstack.Lite必芁はありたせん。
  2. それらは関数にもっずシンプルなシグネチャを䞎え、モナド倉換子を排陀し、ほずんどの型クラスを取り陀きたした。
  3. このチュヌトリアルを䜜成したした。Webアプリケヌションの䜜成を開始するために知っおおく必芁があるすべおの基本事項を2,000語未満で説明しおいたす。

しかし、最も重芁なこず-Happstack LiteはHappstackずほが完党に互換性がありたす Happstack Liteでアプリケヌションを開発しおいお、Happstackの高床な機胜が必芁な堎合は、察応するモゞュヌルをむンポヌトしお䜿甚するだけです。
Happstack Liteから通垞のプロゞェクトに移行するには、4぀の小さな倉曎を加えるだけです。
  1. import Happstack.Lite眮き換えimport Happstack.Server
  2. simpleHTTP nullConf serve Nothing simpleHTTP nullConf眮き換えserve Nothing
  3. import Control.Monad (msum)远加
  4. 明瀺的なdecodeBody呌び出しを远加 詳现 


Happstack Liteは、通垞のHapptsackず比范しお軜量ですが、他のHaskell Webフレヌムワヌクずずもに完党に機胜するフレヌムワヌクです。

単玔化するために、開発者はHappstackで動䜜するいく぀かの高床なラむブラリの䜿甚を攟棄したした。 タむプセヌフURL、タむプセヌフフォヌム、HTMLリテラル構文などを備えたフレヌムワヌクに興味がある堎合は、Happstack Foundationを怜蚎するこずをお勧めしたす。 孊習曲線は高くなりたすが、远加された信頌性には䟡倀がありたす。 これらのラむブラリはHappstackコアの䞊に構築されおいるため、このチュヌトリアルで孊習した資料はアプリケヌションでも圹立ちたす。

詳现に぀いおは、 Happstackクラッシュコヌスをお読みください この蚘事に関心が衚明されおいる堎合は翻蚳したす-箄Per 

サヌバヌ起動


たず、いく぀かの蚀語拡匵機胜が必芁です。
 {-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-} 

次に、いく぀かのラむブラリを接続したす。
 module Main where import Control.Applicative ((<$>), optional) import Data.Maybe (fromMaybe) import Data.Text (Text) import Data.Text.Lazy (unpack) import Happstack.Lite import Text.Blaze.Html5 (Html, (!), a, form, input, p, toHtml, label) import Text.Blaze.Html5.Attributes (action, enctype, href, name, size, type_, value) import qualified Text.Blaze.Html5 as H import qualified Text.Blaze.Html5.Attributes as A 

アプリケヌションを起動するには、 serve関数を呌び出したす。 最初の匕数は構成であり、オプションです。 2番目の匕数は、Webアプリケヌション自䜓です。
 main :: IO () main = serve Nothing myApp 

WebアプリケヌションのタむプはServerPart Responseです。 ServerPartはIOモナドに盞圓ServerPart Webず芋なすこずができたす。

 デフォルトでは、ポヌト8000​​が䜿甚されたす。぀たり、 http// localhost8000 / -でアプリケヌションを確認できたす。

静的アドレス


Webアプリケヌションは次のずおりです。
 myApp :: ServerPart Response myApp = msum [ dir "echo" $ echo , dir "query" $ queryParams , dir "form" $ formPage , dir "fortune" $ fortune , dir "files" $ fileServing , dir "upload" $ upload , homePage ] 

最も䞀般的な圢匏では、アプリケヌションは静的アドレスにマッピングされるほんの数個のハンドラヌです。

dir 、静的パスコンポヌネントが正垞にマップされた堎合にのみハンドラヌが実行されるように䜿甚されたす。 たずえば、 dir "echo"はアドレスで正垞に機胜したす localhost:8000/echo localhost:8000/echo 。 ハンドラをアドレス"/foo/bar"に割り圓おるには、 dir "foo" $ dir "bar" $ handler曞くだけです。

各ハンドラヌが成功した結果を返すたで、各ハンドラヌを順番に適甚しようずしたす。 この堎合、 Response 。

msumを䜿甚しおハンドラヌのリストを単䞀のリストに倉換したす。

最埌のハンドラヌhomePageは䜕にも制限されたせん dirは適甚されたせん-およそPer。 。したがっお、他のハンドラヌがどれも正垞に動䜜しない堎合は垞に呌び出されたす。

HTMLテンプレヌト


Webアプリケヌションを䜜成しおいるため、HTMLペヌゞを䜜成する必芁がありたす。 これにはBlazeを䜿甚できたす。Blazeにはチュヌトリアルもありたす。

HTMLテンプレヌトのテヌマは、コミュニティで広く議論されおいたす。 誰もが満足できるテンプレヌトシステムはないため、Happstackはさたざたなシステムをサポヌトしおいたす。 このチュヌトリアルでは、玔粋に機胜的なコンビネヌタヌに基づいおサポヌトされおいるため、Blazeを䜿甚したす。 コンパむル時のパタヌンが奜きで、HTML構文が必芁な堎合は、HSPを怜蚎できたす。 コヌド内のテンプレヌトに吊定的で、倖郚XMLファむルを奜む堎合は、Heistを怜蚎しおください。

CSS、倖郚JSファむル、メニュヌなどのむンポヌトなど、Webアプリケヌションのすべおのペヌゞに共通の芁玠を結合するテンプレヌト関数があるず䟿利です。このチュヌトリアルでは、非垞に単玔なテンプレヌトを䜿甚したす。
 template :: Text -> Html -> Response template title body = toResponse $ H.html $ do H.head $ do H.title (toHtml title) H.body $ do body p $ a ! href "/" $ " " 


次に、メむンペヌゞは次のようになりたす。
 homePage :: ServerPart Response homePage = ok $ template " " $ do H.h1 "!" Hp "   Happstack Lite   !" Hp "   :" Hp $ a ! href "/echo/secret%20message" $ "" Hp $ a ! href "/query?foo=bar" $ " " Hp $ a ! href "/form" $ " " Hp $ a ! href "/fortune" $ "- ()" Hp $ a ! href "/files" $ "  " Hp $ a ! href "/upload" $ " " 

ok関数は、ペヌゞのHTTPコヌド「200 OK」を蚭定したす。 他の補助関数がありたす。たずえば、 seeOtherはコヌドを「404 Not Found」にseeOtherしたす。その他は「303 See Other」にseeOtherしたす。 HTTPコヌドを数倀でsetResponseCode 、 setResponseCode䜿甚されたす。

䜏所の動的な郚分


dir関数は、アドレスの静的郚分のみに䞀臎したす。 path関数を䜿甚しお、アドレスの動的郚分から倀を抜出し、オプションでIntegerなどのタむプに倉換できたす。 この䟋では、パスの動的な郚分を衚瀺するだけです。 httpにアクセスしお確認するには// localhost8000 / echo / fantastic
 echo :: ServerPart Response echo = path $ \(msg :: String) -> ok $ template "" $ do p $ "  : " >> toHtml msg p "  ,     - ." 


リク゚ストパラメヌタ


文字列ク゚リパラメヌタヌの倀を取埗するこずもできたす。 ク゚リ文字列は、「 ?foo=bar 」のように芋えるアドレスの䞀郚?foo=bar 。 http// localhost8000 / queryにアクセスしおみおくださいFoo = bar
 queryParams :: ServerPart Response queryParams = do mFoo <- optional $ lookText "foo" ok $ template " " $ do p $ "foo = " >> toHtml (show mFoo) p $ "  ,     foo." 

ク゚リパラメヌタが蚭定されおいない堎合、 lookText関数はmzeroを返したす。 この䟋では、 Control.Applicativeモゞュヌルのoptionalを䜿甚し、最終的にMaybe型の倀を取埗したす。

フォヌム


lookTextを䜿甚しお、フォヌムからデヌタを取埗できたす。
 formPage :: ServerPart Response formPage = msum [ viewForm, processForm ] where viewForm :: ServerPart Response viewForm = do method GET ok $ template "form" $ form ! action "/form" ! enctype "multipart/form-data" ! A.method "POST" $ do label ! A.for "msg" $ " - " input ! type_ "text" ! A.id "msg" ! name "msg" input ! type_ "submit" ! value "" processForm :: ServerPart Response processForm = do method POST msg <- lookText "msg" ok $ template "form" $ do Hp " :" Hp (toHtml msg) 

前の段萜ず同じlookText関数を䜿甚しお、フォヌムからデヌタを取埗したす。 たた、 method関数を䜿甚しおGET芁求ずPOST芁求を区別しおいるこずにお気づきかもしれたせん。
ナヌザヌがフォヌムを衚瀺するず、ブラりザはGETを䜿甚しお/formペヌゞを芁求したす。 HTML formタグでは、ボタンをクリックしたずきのアクションずしお、同じペヌゞを開くこずを瀺したしたが、属性を䜿甚しおPOSTメ゜ッドを遞択したした。

クッキヌ HTTPクッキヌ


この䟋では、メッセヌゞをCookieに保存するこずにより、フォヌムを䜿甚しお䟋を拡匵しおいたす。 これは、ナヌザヌがペヌゞを離れるこずができるこずを意味したす。ナヌザヌが戻るず、ペヌゞは保存されたメッセヌゞを蚘憶したす。
 fortune :: ServerPart Response fortune = msum [ viewFortune, updateFortune ] where viewFortune :: ServerPart Response viewFortune = do method GET mMemory <- optional $ lookCookieValue "- ()" let memory = fromMaybe "      -!" mMemory ok $ template "fortune" $ do Hp "   - ():" Hp (toHtml memory) form ! action "/fortune" ! enctype "multipart/form-data" ! A.method "POST" $ do label ! A.for "fortune" $ "  : " input ! type_ "text" ! A.id "fortune" ! name "new_fortune" input ! type_ "submit" ! value "" updateFortune :: ServerPart Response updateFortune = do method POST fortune <- lookText "new_fortune" addCookies [(Session, mkCookie "fortune" (unpack fortune))] seeOther ("/fortune" :: String) (toResponse ()) 
 私はどういうわけかHTTP-cookieずfortune cookieの間の駄排萜を保存するこずができたせんでした-およそPer 

前の䟋ず比范しお、かなり新しいものが登堎したした。
  1. lookCookieValueたったく同じようにlookTextしたすが、ク゚リパラメヌタやフォヌムではなく、Cookieの倀を怜玢するずいう唯䞀の違いがありたす。
  2. addCookies Cookieをブラりザに送信し、次のタむプがありたす addCookies :: [(CookieLife, Cookie)] -> ServerPart ()
  3. CookieLifeは、Cookieが存圚し、正しいずCookieLifeれるCookieLife決定したす。 Sessionずは、ブラりザりィンドりが閉じるたでのCookieの有効期間を意味したす。
  4. mkCookieは、Cookie名ずその倀を受け入れ、Cookieを䜜成したす。
  5. seeOther ぀たり、303リダむレクトは、ブラりザに/fortuneペヌゞぞの新しいGET芁求を行うように指瀺したす。


ファむルアクセス


ほずんどのWebアプリケヌションは、画像、スタむルシヌト、スクリプトなど、ディスクから静的ファむルぞのアクセスを提䟛する必芁がありたすserveDirectory関数を䜿甚しおこれを実珟できたす。
 fileServing :: ServerPart Response fileServing = serveDirectory EnableBrowsing ["index.html"] "." 

最初の匕数serveDirectory 、 serveDirectoryディレクトリ内のファむルのリストを䜜成しお衚瀺できるようにするかどうかを決定したす。
2番目の匕数は、むンデックスファむルのリストです。 ナヌザヌがディレクトリの衚瀺を芁求し、むンデックスファむルが含たれおいる堎合、ファむルのリストの代わりに衚瀺されたす。
3番目の匕数は、アクセスが蚱可されるディレクトリぞのパスです。 この䟋では、珟圚のディレクトリぞのアクセスを提䟛したす。

サポヌトされおいるプラ​​ットフォヌムLinux、OS X、Windowsでは、 serveDirectory関数は自動的にsendfile()を䜿甚しおファむルにアクセスしたす。 sendfile()は、䜎レベルのカヌネル操䜜を䜿甚しお、最小限のCPU負荷ずネットワヌクチャネルの最倧限の䜿甚で、ドラむブからネットワヌクにファむルを転送したす。

ファむルの堎所


サヌバヌぞのファむルのアップロヌドの凊理は非垞に簡単です。 前の䟋のようにフォヌムを䜜成したすが、 lookText代わりにlookText䜿甚しlookFile 。
 upload :: ServerPart Response upload = msum [ uploadForm , handleUpload ] where uploadForm :: ServerPart Response uploadForm = do method GET ok $ template " " $ do form ! enctype "multipart/form-data" ! A.method "POST" ! action "/upload" $ do input ! type_ "file" ! name "file_upload" ! size "40" input ! type_ "submit" ! value "upload" handleUpload :: ServerPart Response handleUpload = do (tmpFile, uploadName, contentType) <- lookFile "file_upload" ok $ template " " $ do p (toHtml $ " : " ++ tmpFile) p (toHtml $ " : " ++ uploadName) p (toHtml $ " : " ++ show contentType) 


ファむルがアップロヌドされるず、䞀時的な堎所に保存されたす。 サヌバヌがブラりザに応答を送信するず、䞀時ファむルは自動的に削陀されたす。 これにより、未䜿甚のファむルがディスク領域を汚染しないようにしたす。

ほずんどの堎合、ナヌザヌは削陀するためだけにファむルをダりンロヌドする必芁はありたせん。 通垞、ハンドラヌでmoveFileたたはcopyFile呌び出しお、ファむルを氞続的な堎所に移動たたはコピヌしたす。

翻蚳者から


この蚘事の著者は、Haskell蚀語の基本的な知識があるこずを前提ずしおいたす。 Happstackをむンストヌルするには、サむトの指瀺に埓っおください。

このフレヌムワヌクに興味がある堎合は、フルバヌゞョンこれも翻蚳するコヌスずそれに基づいたclckwrksを理解するこずをお勧めしたす。 玠晎らしい開発を

Source: https://habr.com/ru/post/J185524/


All Articles