TechTalk:Yesod を支える技術     石井 大海
自己紹介• 石井 大海• 早稲田大学基幹理工学部 数学科三年(四月より)• Twitter Crawler などを書いている• Haskell Lover
Haskell Lover• Haskell :純粋関数型言語 • 型クラスによる強力な抽象化能力 • 純粋性に由来するモジュラリティ• 今日の発表は Haskell 製Web Framework Yesod について
Haskell のWeb開発• 既にたなかさんが発表済みでは?• Yesod は Haskell の技術の結晶 • Yesod から Haskell の “今” を知ろう!
Yesod の特徴
Yesod の特徴•   セキュア、XSS/SQL injection に強い
Yesod の特徴•   セキュア、XSS/SQL injection に強い•   抽象度の高いデータベースアクセス
Yesod の特徴•   セキュア、XSS/SQL injection に強い•   抽象度の高いデータベースアクセス•   型付きURL
Yesod の特徴•   セキュア、XSS/SQL injection に強い•   抽象度の高いデータベースアクセス•   型付きURL•   柔軟なテンプレートシステム
Yesod の特徴•   セキュア、XSS/SQL injection に強い•   抽象度の高いデータベースアクセス•   型付きURL•   柔軟なテンプレートシステム•   継続ビルド
Yesod の特徴•   セキュア、XSS/SQL injection に強い•   抽象度の高いデータベースアクセス•   型付きURL•   柔軟なテンプレートシステム•   継続ビルド•   高速
Yesod の特徴•   セキュア、XSS/SQL injection に強い•   抽象度の高いデータベースアクセス•   型付きURL•   柔軟なテンプレートシステム•   継続ビルド•   高速•   柔軟なバックエンド(Standal...
XSS / SQL injection に強い
XSS / SQL injection に強い•   型による区別
XSS / SQL injection に強い•   型による区別    •   String, Text: 文字列型を埋め込む際は必ずエス        ケープされる
XSS / SQL injection に強い•   型による区別    •   String, Text: 文字列型を埋め込む際は必ずエス        ケープされる    •   生HTMLを埋め込むには手動で Html 型に変      ...
XSS / SQL injection に強い•   型による区別    •   String, Text: 文字列型を埋め込む際は必ずエス        ケープされる    •   生HTMLを埋め込むには手動で Html 型に変      ...
SQL injection に強い• 抽象度の高いレイヤによって生の部分 は隠• そもそも non-relational な使い方を前提 としているので低レベルを叩く必要性 が殆んどない • 一応用意されてはいる
抽象度の高いDBアクセス•   使用出来るバックエンド    •   PostgreSQL, Sqlite3, MongoDB    •   MySQL, CouchDB も試験的に使用可能•   殆んど共通のAPIを利用可能    •   n...
抽象度の高いDBアクセスclass PersistStore b m where  insert :: PersistEntity val => val → b m (Key b val)  insertKey :: PersistEntity...
抽象度の高いDBアクセス•   データベースに格納出来る値のクラス•   関連型の機能を使っている    •    型クラスに付随する函数のようなもの    •    識別子やバックエンド、フィールドを表現する型などclass PersistE...
全部記述するの?  User      ident UserName      password Text      salt     Text Maybe      UniqueUser ident  Email      email Tex...
全部記述するの?•   コンパイル時に自動生成!           User               ident UserName               password Text               salt     Te...
全部記述するの?•   コンパイル時に自動生成!    •   Template Haskell / Quasi Quote の威力                   User                       ident User...
全部記述するの?•   コンパイル時に自動生成!    •   Template Haskell / Quasi Quote の威力        •   Haskell のコンパイルタイムプログラムの手法・リーダマクロ            ...
全部記述するの?•   コンパイル時に自動生成!    •   Template Haskell / Quasi Quote の威力        •   Haskell のコンパイルタイムプログラムの手法・リーダマクロ            ...
全部記述するの?•   コンパイル時に自動生成!    •   Template Haskell / Quasi Quote の威力        •   Haskell のコンパイルタイムプログラムの手法・リーダマクロ            ...
型付きURL•   関連型・Template Haskell の利用例。•   リンク切れや不正リンクを型レベルで防止!    /static StaticR Static getStatic    /auth AuthR Auth getAu...
処理函数    getTreeR :: String ! ObjPiece ! Handler RepHtml    getTreeR repon op@(ObjPiece com xs) =     withRepoObj repon op ...
テンプレートシステム• Shakespeare Template • Hamlet / Cassius / Lucius / Julius /    CoffeeScript などなど  • 型安全かつ効率的な Template Languag...
テンプレート    <ul>      $forall ent <- entries         $if isRegularFile ent           <li><a href=@{BlobR repon (mkP ent)}>#{...
補足• Html型:blaze-html ライブラリ由来の型 • 効率的な文字列処理ライブラリ • 先程の例ではMarkdownを自動で整形  して表示していたりする(!!!)• CSS や JSのテンプレートと合わせて巧 いことやってくれる
継続ビルド
継続ビルド• コンパイラ言語でWeb開発
継続ビルド• コンパイラ言語でWeb開発 • 書き換える度に recompile は面倒
継続ビルド• コンパイラ言語でWeb開発 • 書き換える度に recompile は面倒 • Yesod なら自動再コンパイル!
継続ビルド• コンパイラ言語でWeb開発 • 書き換える度に recompile は面倒 • Yesod なら自動再コンパイル!•   コードやテンプレートの書き換えを自動感知
継続ビルド
継続ビルド• GHC API を利用
継続ビルド• GHC API を利用 • ……していた。
継続ビルド• GHC API を利用 • ……していた。 • 現在はファイルを監視して、外部コマ  ンドを呼び出し再コンパイルしている
悔しいのでGHC API
悔しいのでGHC API•   GHC (Haskell のコンパイラ) の機能を埋め    込める
悔しいのでGHC API•   GHC (Haskell のコンパイラ) の機能を埋め    込める    •   通常 hint と云うラッパを挟んで使用
悔しいのでGHC API•   GHC (Haskell のコンパイラ) の機能を埋め    込める    •   通常 hint と云うラッパを挟んで使用    •   Haskelインタプリタを仕込める
悔しいのでGHC API•   GHC (Haskell のコンパイラ) の機能を埋め    込める    •   通常 hint と云うラッパを挟んで使用    •   Haskelインタプリタを仕込める        •   プラグインなど...
悔しいのでGHC API•   GHC (Haskell のコンパイラ) の機能を埋め    込める    •   通常 hint と云うラッパを挟んで使用    •   Haskelインタプリタを仕込める        •   プラグインなど...
高速・高効率• What make it possible? • ByteString / Text • blaze • Conduit
ByteString / Text
ByteString / Text• 「Haskell の文字列処理は遅い」
ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」
ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」• (本物の)文字列型を使おう!
ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」• (本物の)文字列型を使おう! • ByteString:Byteの配列
ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」• (本物の)文字列型を使おう! • ByteString:Byteの配列 • Text:Unicode 対応版。BSよ...
blaze• blaze-builder • ByteString 合成用のライブラリ。  差分リストを用いて効率を上げてい  る、らしい。 • Text にも類似の機能がある。• blaze-html が元々の発祥だった。
benchmark• 10000 個の文字列片を連結     String                                              binary ByteString                      ...
Conduit• 遅延I / Oに代わる Functional な IO 手法 • Source:入力源 • Conduit:入力を加工するパイプ • Sink:出力先 • ストリーム処理のような形になる。
Conduit• ResourceT • リソースの解放処理を担当するモナド • lifted-base を利用し例外安全   • 先進的な例外ライブラリ。詳細は   たなかさんの発表資料を参照。
Conduit•   Iteratee パターンに対する代替案    •   例外処理が超面倒    •   入力源を引き回せない    •   Iteratee では出力先の資源を割り当てられ        ないと云う問題があった      ...
Conduit• Conduit とは結局何か? • 入力と出力、中間処理の抽象化!
柔軟なバックエンド•   Yesod アプリは……    •   Standalone なサーバ        •   Warp, Snap, ...    •   CGI    •   FastCGI    •   (開発用継続ビルドサーバ)...
柔軟なバックエンド• WAI: Web Application Interface • ウェブアプリを抽象化するインター     フェース。 • Ruby の rack、Python の WSGI に相当 •   type Applicatio...
バックエンド• Warp:爆速HTTPサーバ• Snap:ミニマルなウェブフレームワーク• CGI, Fast-CGI:普通のサーバ上でも動く• 開発用サーバ:自動コンパイルとかの奴
Benchmark• Pong benchmark (Yesod公式より) • Higher is Faster       90000       67500       45000       22500             0   g...
結論• Web アプリ向き技術が Haskell には沢山• Web アプリが Haskell の技術を必要とし  ているとも云える• Haskell はライブラリも言語機能もアツ  い!• Write Your Web App by Hask...
Any Questions?
御清聴ありがとうございました。
Upcoming SlideShare
Loading in...5
×

Yesodを支える技術

10,431

Published on

社内 TechTalk での資料。Yesod に用いられている Haskell の先進的な機能について軽く解説しています。

Published in: Technology
0 Comments
29 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
10,431
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
49
Comments
0
Likes
29
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Yesodを支える技術

    1. 1. TechTalk:Yesod を支える技術 石井 大海
    2. 2. 自己紹介• 石井 大海• 早稲田大学基幹理工学部 数学科三年(四月より)• Twitter Crawler などを書いている• Haskell Lover
    3. 3. Haskell Lover• Haskell :純粋関数型言語 • 型クラスによる強力な抽象化能力 • 純粋性に由来するモジュラリティ• 今日の発表は Haskell 製Web Framework Yesod について
    4. 4. Haskell のWeb開発• 既にたなかさんが発表済みでは?• Yesod は Haskell の技術の結晶 • Yesod から Haskell の “今” を知ろう!
    5. 5. Yesod の特徴
    6. 6. Yesod の特徴• セキュア、XSS/SQL injection に強い
    7. 7. Yesod の特徴• セキュア、XSS/SQL injection に強い• 抽象度の高いデータベースアクセス
    8. 8. Yesod の特徴• セキュア、XSS/SQL injection に強い• 抽象度の高いデータベースアクセス• 型付きURL
    9. 9. Yesod の特徴• セキュア、XSS/SQL injection に強い• 抽象度の高いデータベースアクセス• 型付きURL• 柔軟なテンプレートシステム
    10. 10. Yesod の特徴• セキュア、XSS/SQL injection に強い• 抽象度の高いデータベースアクセス• 型付きURL• 柔軟なテンプレートシステム• 継続ビルド
    11. 11. Yesod の特徴• セキュア、XSS/SQL injection に強い• 抽象度の高いデータベースアクセス• 型付きURL• 柔軟なテンプレートシステム• 継続ビルド• 高速
    12. 12. Yesod の特徴• セキュア、XSS/SQL injection に強い• 抽象度の高いデータベースアクセス• 型付きURL• 柔軟なテンプレートシステム• 継続ビルド• 高速• 柔軟なバックエンド(Standalone、CGI、FCGI)
    13. 13. XSS / SQL injection に強い
    14. 14. XSS / SQL injection に強い• 型による区別
    15. 15. XSS / SQL injection に強い• 型による区別 • String, Text: 文字列型を埋め込む際は必ずエス ケープされる
    16. 16. XSS / SQL injection に強い• 型による区別 • String, Text: 文字列型を埋め込む際は必ずエス ケープされる • 生HTMLを埋め込むには手動で Html 型に変 換してやる必要がある
    17. 17. XSS / SQL injection に強い• 型による区別 • String, Text: 文字列型を埋め込む際は必ずエス ケープされる • 生HTMLを埋め込むには手動で Html 型に変 換してやる必要がある • 漏れにくい、何処で漏れているか判りやすい
    18. 18. SQL injection に強い• 抽象度の高いレイヤによって生の部分 は隠• そもそも non-relational な使い方を前提 としているので低レベルを叩く必要性 が殆んどない • 一応用意されてはいる
    19. 19. 抽象度の高いDBアクセス• 使用出来るバックエンド • PostgreSQL, Sqlite3, MongoDB • MySQL, CouchDB も試験的に使用可能• 殆んど共通のAPIを利用可能 • non-relational なモデルを前提としている • 型クラスによる高度な抽象化
    20. 20. 抽象度の高いDBアクセスclass PersistStore b m where insert :: PersistEntity val => val → b m (Key b val) insertKey :: PersistEntity val => Key b val → val → b m () repsert :: PersistEntity val => Key b val → val → b m () replace :: PersistEntity val => Key b val → val → b m () delete :: PersistEntity val => Key b val → b m () get :: PersistEntity val => Key b val → b m (Maybe val) • DBバックエンドの型クラス。 • 函数の意味を型が雄弁に物語っている
    21. 21. 抽象度の高いDBアクセス• データベースに格納出来る値のクラス• 関連型の機能を使っている • 型クラスに付随する函数のようなもの • 識別子やバックエンド、フィールドを表現する型などclass PersistEntity val where data EntityField val :: * → * type PersistEntityBackend val :: ((* → *) → * → *) data Unique val :: ((* → *) → * → *) → * persistFieldDef :: EntityField val typ → FieldDef entityDef :: val → EntityDef toPersistFields :: val → [SomePersistField] fromPersistValues :: [PersistValue] → Either T.Text val
    22. 22. 全部記述するの? User ident UserName password Text salt Text Maybe UniqueUser ident Email email Text user UserId Maybe verkey Text Maybe UniqueEmail email
    23. 23. 全部記述するの?• コンパイル時に自動生成! User ident UserName password Text salt Text Maybe UniqueUser ident Email email Text user UserId Maybe verkey Text Maybe UniqueEmail email
    24. 24. 全部記述するの?• コンパイル時に自動生成! • Template Haskell / Quasi Quote の威力 User ident UserName password Text salt Text Maybe UniqueUser ident Email email Text user UserId Maybe verkey Text Maybe UniqueEmail email
    25. 25. 全部記述するの?• コンパイル時に自動生成! • Template Haskell / Quasi Quote の威力 • Haskell のコンパイルタイムプログラムの手法・リーダマクロ User ident UserName password Text salt Text Maybe UniqueUser ident Email email Text user UserId Maybe verkey Text Maybe UniqueEmail email
    26. 26. 全部記述するの?• コンパイル時に自動生成! • Template Haskell / Quasi Quote の威力 • Haskell のコンパイルタイムプログラムの手法・リーダマクロ User ident UserName password Text salt Text Maybe UniqueUser ident Email email Text user UserId Maybe verkey Text Maybe UniqueEmail email• 一意識別子やクェリの種類(Eq, Lt, Gt)なども指定
    27. 27. 全部記述するの?• コンパイル時に自動生成! • Template Haskell / Quasi Quote の威力 • Haskell のコンパイルタイムプログラムの手法・リーダマクロ User ident UserName password Text salt Text Maybe UniqueUser ident Email email Text user UserId Maybe verkey Text Maybe UniqueEmail email• 一意識別子やクェリの種類(Eq, Lt, Gt)なども指定• これがおよそ300行程度(!!)に展開される
    28. 28. 型付きURL• 関連型・Template Haskell の利用例。• リンク切れや不正リンクを型レベルで防止! /static StaticR Static getStatic /auth AuthR Auth getAuth /favicon.ico FaviconR GET /robots.txt RobotsR GET /repo/#String/tree/*ObjPiece TreeR GET /repo/#String/blob/*ObjPiece BlobR GET /repo/#String/commits/*ObjPiece CommitsR GET • Method も指定可能(REST APIが作りやすい) • リンク用の関連型も自動生成 • あとは各routeに対する処理函数を書くだけ • 静的ファイルへのリンク函数も生成してくれる
    29. 29. 処理函数 getTreeR :: String ! ObjPiece ! Handler RepHtml getTreeR repon op@(ObjPiece com xs) = withRepoObj repon op $ git repo obj ! do unless (isTree obj) $ notFound let src = getReadmeFromGitObj obj readme = writeHtml defaultWriterOptions $ readMarkdown defaultParserState <$> src entries ← liftIO $ getGitTree git repo repoLayout repon op $ do setTitle $ fromString $ repon ++ " - Gitolist" $(widgetFile "tree")• レスポンスの種類を型レベルで限定• 外部テンプレート群からソースをコンパイ ル時生成• IO処理なども(エラー処理込みで)行える
    30. 30. テンプレートシステム• Shakespeare Template • Hamlet / Cassius / Lucius / Julius / CoffeeScript などなど • 型安全かつ効率的な Template Language • 簡単な式の埋め込み、URLと Widget、文字列などの区別
    31. 31. テンプレート <ul> $forall ent <- entries $if isRegularFile ent <li><a href=@{BlobR repon (mkP ent)}>#{fileName ent} $elseif isDirectory ent <li><a href=@{TreeR repon (mkP ent)}>#{fileName ent} $else <li>#{fileName ent} $maybe rm <- readme <h3> README <article> #{rm}• HTML の終了タグをomitした形 • インデントで親子関係• @{..}で型付URL、#{..}で文字やHtmlの埋め込み
    32. 32. 補足• Html型:blaze-html ライブラリ由来の型 • 効率的な文字列処理ライブラリ • 先程の例ではMarkdownを自動で整形 して表示していたりする(!!!)• CSS や JSのテンプレートと合わせて巧 いことやってくれる
    33. 33. 継続ビルド
    34. 34. 継続ビルド• コンパイラ言語でWeb開発
    35. 35. 継続ビルド• コンパイラ言語でWeb開発 • 書き換える度に recompile は面倒
    36. 36. 継続ビルド• コンパイラ言語でWeb開発 • 書き換える度に recompile は面倒 • Yesod なら自動再コンパイル!
    37. 37. 継続ビルド• コンパイラ言語でWeb開発 • 書き換える度に recompile は面倒 • Yesod なら自動再コンパイル!• コードやテンプレートの書き換えを自動感知
    38. 38. 継続ビルド
    39. 39. 継続ビルド• GHC API を利用
    40. 40. 継続ビルド• GHC API を利用 • ……していた。
    41. 41. 継続ビルド• GHC API を利用 • ……していた。 • 現在はファイルを監視して、外部コマ ンドを呼び出し再コンパイルしている
    42. 42. 悔しいのでGHC API
    43. 43. 悔しいのでGHC API• GHC (Haskell のコンパイラ) の機能を埋め 込める
    44. 44. 悔しいのでGHC API• GHC (Haskell のコンパイラ) の機能を埋め 込める • 通常 hint と云うラッパを挟んで使用
    45. 45. 悔しいのでGHC API• GHC (Haskell のコンパイラ) の機能を埋め 込める • 通常 hint と云うラッパを挟んで使用 • Haskelインタプリタを仕込める
    46. 46. 悔しいのでGHC API• GHC (Haskell のコンパイラ) の機能を埋め 込める • 通常 hint と云うラッパを挟んで使用 • Haskelインタプリタを仕込める • プラグインなどの動的ロードができる
    47. 47. 悔しいのでGHC API• GHC (Haskell のコンパイラ) の機能を埋め 込める • 通常 hint と云うラッパを挟んで使用 • Haskelインタプリタを仕込める • プラグインなどの動的ロードができる • 勿論型安全
    48. 48. 高速・高効率• What make it possible? • ByteString / Text • blaze • Conduit
    49. 49. ByteString / Text
    50. 50. ByteString / Text• 「Haskell の文字列処理は遅い」
    51. 51. ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」
    52. 52. ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」• (本物の)文字列型を使おう!
    53. 53. ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」• (本物の)文字列型を使おう! • ByteString:Byteの配列
    54. 54. ByteString / Text• 「Haskell の文字列処理は遅い」 • String 型……ただの文字の「リスト」• (本物の)文字列型を使おう! • ByteString:Byteの配列 • Text:Unicode 対応版。BSより若干効 率が下がるが String より遥かに高効率
    55. 55. blaze• blaze-builder • ByteString 合成用のライブラリ。 差分リストを用いて効率を上げてい る、らしい。 • Text にも類似の機能がある。• blaze-html が元々の発祥だった。
    56. 56. benchmark• 10000 個の文字列片を連結 String binary ByteString blaze Text 0ms 4ms 8ms 12ms 16ms
    57. 57. Conduit• 遅延I / Oに代わる Functional な IO 手法 • Source:入力源 • Conduit:入力を加工するパイプ • Sink:出力先 • ストリーム処理のような形になる。
    58. 58. Conduit• ResourceT • リソースの解放処理を担当するモナド • lifted-base を利用し例外安全 • 先進的な例外ライブラリ。詳細は たなかさんの発表資料を参照。
    59. 59. Conduit• Iteratee パターンに対する代替案 • 例外処理が超面倒 • 入力源を引き回せない • Iteratee では出力先の資源を割り当てられ ないと云う問題があった • Push から Pull 型へ。モナドの種類も制限
    60. 60. Conduit• Conduit とは結局何か? • 入力と出力、中間処理の抽象化!
    61. 61. 柔軟なバックエンド• Yesod アプリは…… • Standalone なサーバ • Warp, Snap, ... • CGI • FastCGI • (開発用継続ビルドサーバ)• などなど様々な形で動かせる。
    62. 62. 柔軟なバックエンド• WAI: Web Application Interface • ウェブアプリを抽象化するインター フェース。 • Ruby の rack、Python の WSGI に相当 • type Application = Request → ResourceT IO Response type Middleware = Application → Application • 一目瞭然! • Conduit のお陰でこの様な抽象化が可能に。
    63. 63. バックエンド• Warp:爆速HTTPサーバ• Snap:ミニマルなウェブフレームワーク• CGI, Fast-CGI:普通のサーバ上でも動く• 開発用サーバ:自動コンパイルとかの奴
    64. 64. Benchmark• Pong benchmark (Yesod公式より) • Higher is Faster 90000 67500 45000 22500 0 goliath tornado php winstone node snap happstack warp+yesod warp
    65. 65. 結論• Web アプリ向き技術が Haskell には沢山• Web アプリが Haskell の技術を必要とし ているとも云える• Haskell はライブラリも言語機能もアツ い!• Write Your Web App by Haskell!
    66. 66. Any Questions?
    67. 67. 御清聴ありがとうございました。
    1. ¿Le ha llamado la atención una diapositiva en particular?

      Recortar diapositivas es una manera útil de recopilar información importante para consultarla más tarde.

    ×