HaskellのWeb系ライブラリ紹介
はじめに
こんにちは、ishiy(@ishiy1993)です。
この記事はCAMPHOR- Advent Calendar 2016の11日目の記事です。
すでにHaskell Advent Calendar 2016の7日目の記事でHaskellのライブラリ紹介がありましたが、 Web関係に特化することで差別化をはかります。
ときどき「HaskellでもWebまわりできるんですね!?」というのを聞くのでいろいろなライブラリあるよというアピールをしたい。
以下では、僕が使用したことのあるライブラリを中心にサーバー、クライアントそれぞれを紹介していきます。
サーバー
Webサーバー
まずサーバーサイドの基礎になっているライブラリを紹介します。 waiはWeb Application InterfaceでApplication
という型を定義しています。 これが下で紹介するWAFがつくりだすもので、Application
はwarpの中のrun
という関数でWebサーバーとして実行することができます。
waiにはMiddleware
という型もtype Middleware = Application -> Application
と定義されていて、 これを利用することでApplication
にさまざまな機能を追加できます。 Middleware
はwai-extraというパッケージにまとまっていて、 Basic認証やログなどの機能をWAFで作成したApplication
に簡単に追加できます。
Webアプリケーションフレームワーク
次にWAFを見ていきます。上の4つ以外にもsnapやapiaryなどがありますが、これらは使用したことがないので紹介できません。
yesodは重量級のWAFです。O’Reillyから本が出ていて、これを読むとひと通りの機能がなんとか使えるようになります。 型を活用して安全にWebアプリケーションを開発できるというのがいいところですが、いろいろヘビーすぎて使用しているとだんだんつらくなってくるときもあります。 がっちり堅牢なもの、安全第一なものを開発するときには選択肢になると思います。ただそれ以外の場合には他のWAFをおすすめします。 Yesod Advent Calendar 2016なんてものもあります。
scottyはライトなWAFです。ルーティングの機能を提供しているだけで、セッションやデータベース連携の機能はありません。 しゅっと開発したいときにおすすめです。
Spockはscottyとyesodの中間くらいのWAFです。ルーティング、セッション管理、データベース連携の機能があります。 scottyでは機能が足りないけど、yesodは重いなというときにちょうどいい感じです。 Haskell Day 2016でのlotzさんの発表資料が参考になると思います。
servantはひと味ちがったWAFです。ルーティング(API)を型で定義します。 これによってAPIからのレスポンスのデータ型が正しいかもコンパイラがチェックしてくれます。 さらに、APIをたたくJavaScriptやAPIのドキュメントを生成する機能もあります。 RESTfulなJSON APIを作成したいときには、特におすすめです。 とりあえず公式ドキュメントのTutorialを読みましょう。
データベース
persistentは、yesodの人達によって開発されていますがyesod以外のWAFとも組み合せて使用できます。 テーブルの定義をEDSLで書くと、テーブルごとに対応する型が生成されます。 さらに、アプリの初回起動時にテーブルを自動で作成してくれます。 PostgreSQL、SQLite、MySQL、MongoDBに対応していて、実験的にRedisもサポートしているようです。 簡単なデータベース操作は、SQLのことを考えずに定義されている関数を使用することで十分できます。 複雑なSQLを使いたいときは、esqueletoと組みあわせるようです。 (僕はesqueletoを使用したことがないので使用感はわかりません)
relational-recordは、型を利用して安全なSQLを生成してくれるライブラリです。 HDBCと組み合せることでデータベース操作ができます。 DB2、PostgreSQL、SQLite、MySQL、Microsoft SQL Server、OracleSQLに対応しているようです。 コンパイル時にデータベースからテーブルの定義を読み込んで、テーブルごとに対応する型を自動で生成してくれます。 公式ページのExamplesが充実しているので、大抵の場合どうすればいいかわかります。 Examplesを見てもわからない場合は、ここを見るのがよいと思います。 僕がrelational-recordでつまずいたところはこの記事にまとめたので参考にどうぞ。
新しくテーブルを作成して開発していく場合にはpersistentがおすすめです。 一方で、すでにテーブルが存在していて安全なSQLを使用したいときはrelational-recordがいいと思います。
静的ページジェネレータ
hakyllはmarkdownなどで書かれた記事とテンプレートとなるHTMLファイルから静的ページを生成してくれるライブラリです。 このブログもhakyllを使用して、markdownで記事を書いています。 ページネーションやRSS/Atomの生成、記事のタグ付けなどブログに必要な機能があります。
クライアント
通信
http-conduitはhttp-clientにconduitのインターフェースをつけたものです。 OAuthのヘルパーがないので、Web APIをたたくのに使うのは少し面倒だった印象です。
wreqをlensのインターフェースを持つHTTPクライアントです。 僕は便利で使いやすいライブラリだと思っています。 lensに抵抗がある方はとっつきにくいかもしれません。 開発が最近停滞しているのが残念なところ。
reqは最近登場した新しいライブラリです。 現時点でまだlts-7に入っておらず、nightlyです。 ただこんな感じでextra-depsに加えるとlts-7でも使用できました。 今後、注目のライブラリです。
データの扱い
aesonは、HaskellでJSONを扱うライブラリです。Haskell中でのJSONの表現であるValue
型などが定義されています。 lens-aesonはlensでJSONからデータを取り出せるライブラリです。Value
型に変換する前の文字列({"hoge": "bar"}
のようなもの)から直接JSONのキーを用いてデータにアクセスできるところが特に便利だと感じています。 Web APIをたたくときに重宝します。
xml-conduit、html-conduitはそれぞれXMLとHTMLをパースするライブラリです。 Haskell中でのXML、HTMLの表現はxml-conduitで定義されているDocument
型です。 XMLをDocument
型として読み込むにはxml-conduitのText.XML.readFile
などを使用し、HTMLをDocument
型として読み込むのにはhtml-conduitのText.HTML.DOM.readFile
などを使用します。 一旦Document
型に変換したら、xml-conduitのText.XML.Cursor
中の関数を使ってデータにアクセスします。 xml-lensはDocument
型にlensでアクセスするための関数を提供するライブラリです。
まとめ
HaskellのWeb系ライブラリを紹介しました。
少しでもHaskellやってみようと思った方は、さっそくstackをインストールしましょう。Archlinuxの場合は
$ sudo pacman -S stack
だけです。GHC(コンパイラ)や上で紹介したライブラリはstackを使ってインストールできます。Webの記事を読む上でcabalを使用している記事は古い可能性が高いので注意してください。
間違いなどありましたら、@ishiy1993に連絡していただけると助かります。
CAMPHOR- Advent Calendar 2016の12日目の担当はshiba6vです。お楽しみに。
ではでは。