HaskellのYesodでWebアプリ開発入門 (1)

この記事について

ふと思い立ってHaskellでWebアプリ開発をしたいなと思ったところ、乗り遅れている感は否めないものの、Yesodというフレームワークが一番有名らしいので触ってみることにした。

この記事は、環境構築などの手順を忘れてしまうと勿体無いので、踏んだ手順をメモしておくためのものです。

なので、一応将来的にはEsqueletoも使ってちゃんとしたTDDでRESTfulなWebアプリにしたいと思っていますが、気分が変われば途中で書くのをやめるかもしれないので、入門記事としては期待できないかと思います。

※ 2014年9月13日に Mac OS XのためのHaskell開発環境 - プログラミング芸術論 という記事を書いた関係で、使用バージョンや導入方法の情報を更新しました。

環境

当分は手元のMacBookを使うので、

  • Mac OS X Mavericks (10.9.4)
  • GHC version 7.8.3
  • Yesod version 1.2.12.8
  • Cabal library version 1.20.0.3
  • cabal-install version 1.20.0.2

な環境でのお話です。

ちなみに、筆者のスペックは

  • O'RaillyのReal World Haskellをある程度まで読んだが、もう内容忘れた
  • Webアプリケーション開発はRuby on Rails Tutorialを読んで、アプリケーションを作ってみたり商用プログラミングも少しだけ必要に迫られてやったことがある

という程度なので、解説はほぼできないも同然です。

開発環境の構築

GHCを始めとするHaskellの開発環境、cabalなどの使い方については Mac OS XのためのHaskell開発環境 - プログラミング芸術論 にまとめてありますので、そちらをご覧ください。

Yesodのインストール

まず、Yesodをグローバルにインストールします。

もともとはプロジェクトのsandboxを作成してからYesodもローカルのインストールを行うだけにしていたのですが、それだとYesodの実行ファイルへのパスが通らずにcabal exec yesod develが動かなかったため、Yesodだけはグローバルにインストールするようにしました。

このcabal exec yesod develにパスが通らない件はYesodのGithubレポジトリのissue Cannot use yesod-bin from within the cabal sandbox · Issue #737 · yesodweb/yesod · GitHub でも議論されていますが、この記事を書いている現在では有効な解決策は見つかっていないようなので、プロジェクト内で使うために計2回Yesodの長時間コンパイルを味わうこととなりますが、グローバルにインストールするやり方が一番問題なく済むかと思います。

$ cabal update
$ cabal install yesod-bin --max-backjumps=-1 --reorder-goals -j

reorder-goalsは他のパッケージの依存バージョンなどの関係でインストールするパッケージのバージョンがあわない場合に頑張ってくれるオプションで、--max-backjumps-1を指定することでその試行回数を無制限に設定します。

たくさんのパッケージをインストールするので、驚くほど時間が掛かります。

ちなみに私の環境では上記cabal install実行時にhaskell-platformによってインストールされていたalexとhappyを使おうとしてバージョンが古くてインストールがコケてしまったので、別個にcabal install alex happy -jとしてやる必要がありました。

プロジェクトの作成

新しいプロジェクトはyesod initで作成でき、対話式でプロジェクト名と使用するデータベースソフトを尋ねられます。

$ yesod init
Welcome to the Yesod scaffolder.
I'm going to be creating a skeleton Yesod project for you.

What do you want to call your project? We'll use this for the cabal name.

Project name: yesod-sample
Yesod uses Persistent for its (you guessed it) persistence layer.
This tool will build in either SQLite or PostgreSQL or MongoDB support for you.
We recommend starting with SQLite: it has no dependencies.

    s      = sqlite
    p      = postgresql
    pf     = postgresql + Fay (experimental)
    mongo  = mongodb
    mysql  = MySQL
    simple = no database, no auth
    url    = Let me specify URL containing a site (advanced)

So, what'll it be? mysql
That's it! I'm creating your files now...

---------------------------------------

                     ___
                            {-)   |\
                       [m,].-"-.   /
      [][__][__]         \(/\__/\)/
      [__][__][__][__]~~~~  |  |
      [][__][__][__][__][] /   |
      [__][__][__][__][__]| /| |
      [][__][__][__][__][]| || |  ~~~~
  ejm [__][__][__][__][__]__,__,  \__/


---------------------------------------

The foundation for your web application has been built.


There are a lot of resources to help you use Yesod.
Start with the book: http://www.yesodweb.com/book
Take part in the community: http://yesodweb.com/page/community


It's highly recommended to follow the quick start guide for
installing Yesod: http://www.yesodweb.com/page/quickstart

If your system is already configured correctly, please run:

   cd yesod-sample && cabal install -j --enable-tests --max-backjumps=-1 --reorder-goals && yesod devel

なんか人出てきた...

今回はyesod-sampleという名前のプロジェクトにして、使用するDBMSMySQLを選びました。

依存パッケージのインストール

アプリケーションを起動するには、依存パッケージ(再びYesodの全体を含む...)のインストールとプロジェクト全体のコンパイルおよびインストールをする必要があります。

yesod initの最後に出てきたコマンドではグローバルにプロジェクトをインストールしてしまっていますが、プロジェクトの依存パッケージをグローバルにインストールしてしまうと他のHaskellプロジェクトに影響が出るので、cabalのsandbox機能を有効化してからYesodをインストールします。

$ cd yesod-sample
$ cabal sandbox init
$ cabal install -j --enable-tests --max-backjumps=-1 --reorder-goals

上のコマンドを叩くだけで自動的にプロジェクト全体のコンパイルが行われた上で、プロジェクト全体が他のcabalでインストールするライブラリと同じようにインストールされた状態になります。

--enable-testsはテストのための依存パッケージもインストールするオプションです。 yesod-sample.cabalを見ると依存パッケージやコンパイル時に使用されるオプションなどがデフォルトでどう設定されているかわかります。

ちなみに、build-dependsの記述にあるpersistentっていうのが、Yesodを使う際に現状最もポピュラーなO/R mapperみたいですが、MySQLだけの構文などには弱いみたいなので、ゆくゆくはその拡張のEsqueletoを使ってみたいなと思っています。

で、いよいよサーバの起動ですが、今回はデータベースソフトにMySQLを指定してしまったので、先にその設定を行う必要があります。

データベースの設定とアプリケーションの起動

データベースの情報はconfig/mysql.ymlにあり、RoRconfig/database.ymlとほぼ同じなので、特に迷うことはないかと思います。とりあえずDevelopment環境とTest環境のデータベース設定をしっかりとやって、MySQLでユーザとデータベースの作成を行なっておけばOKでしょう。

ちなみに、データベースの設定ファイルはYAML形式なので、パスワードが数字だけだったり空だったりする場合にはダブルクオーテーションで囲む必要があります。

設定が完了したら、以下のコマンドでアプリケーションを起動します。

$ yesod devel

自動的にソースコードがビルドされ、Scaffoldに含まれているデータベースマイグレーションが行われた後、アプリケーションサーバが起動します。なぜか筆者の環境ではマイグレーションを含む一回目の起動の際にDevel application launchedの表示がされなかったのですが、問題なく起動していました。

localhost:3000にアクセスしてScaffoldのホームページが表示されていれば、起動までのプロセスは完了です。

おわりに

無事環境構築とScaffoldのアプリケーションを起動することができました。

なお、プロジェクトを削除する際には依存パッケージも全てプロジェクトディレクトリ以下に含まれているので、単にディレクトリを削除するだけで済みます。

$ rm -r yesod-sample

次回はScaffoldで生成されたファイルの確認とハンドラの追加までです。