はじめに
前回から、いよいよNode.jsを使ったWebアプリケーションを作成しはじめました。前回はデータを保存および読み出す処理がなかったので、今回はデータベースとの連携を実装したいと思います。使うのはMongoDBです。リレーショナルデータベースに対して、MongoDBはドキュメント指向データベースという位置づけです。JSON構造をそのまま保存できるため、Node.jsとの親和性も高いです。簡単に導入でき、日本語ドキュメントもあるので、初めてでもすんなり使えると思います。
MongoDBのセットアップ
MongoDBのサイトから、OSごとに用意されたアーカイブをダウンロードして展開してください。展開したフォルダの直下にあるbinディレクトリ内にコマンド群があるため、これらを使って操作します。サーバデーモンとなるのがmongodで、クライアントとなるのがmongoになります。
まず適当にデータファイルを置く空ディレクトリを用意してください。そこを指定してmongodを実行するだけサーバが起動します。
なお、MongoDBは基本的に最初から巨大なファイルを用意することで、パフォーマンスを上げる方針で作られているため、デフォルトで起動すると、何もデータを入れてなくてもGB単位でディスク領域を占有します。今回は単に開発で使用するので、ジャーナル機構やデータファイルを先に確保する機構は、無効化しています。フォアグランドで起動するので、CTRL + Cで終了できます。
Mongooseを使ってNode.jsからMongoDBを利用
MongoDBをnodeから利用するには、node-mongodb-nativeという標準ドライバモジュールがあります。今回はそれをさらにO/Rマッパーのように利用できるモジュールMongooseを使って、MongoDBを使ってみます。
前回作成したfirstappのディレクトリで関連モジュールをインストールします。
として利用するモジュールをインストールします。
モデルの実装
続いてmodel.jsというファイル名で、下記のコードを作成定義します。
まず、mongooseモジュールの読み込みです。次にconnectメソッドで、localhostで稼働するMongoDBのfirstappデータベースに接続します。
投稿データをPostというモデルで定義します。Postモデルのスキーマは、textという文字列フィールドと、dateという日付型でデフォルトは現在日時が入るフィールドを定義します。またtextフィールドには、「文字列長が0より大きいか」バリデート関数を指定しています。
modelメソッドは、「Post」という名前でPostモデルのスキーマを登録しています。MongoDB上では、「posts」というコレクション(RDBでいうテーブルに該当)で管理されます。Mongooseによって、小文字かつ複数形に変換された名前となります。戻り値がデータアクセスモデルとなるので、それをexportsに渡して、外から使えるようにします。
アプリケーションの修正
前回作成したroutes/main.jsを修正して、Postモデルを利用するようにします。
はじめに、model.jsを読み込みます。さらにPostモデルを直接利用できるように変数宣言しなおします。
ルートパスにアクセスしたときのリスト表示では、findメソッドを使って、postsコレクションのドキュメントを全て取得しコールバック関数function(err, items)で、結果を処理します。Findメソッドの第1引数は条件(SQLでいうwhere句)を指定できます。この場合全てなので空のオブジェクトにしています。コールバックの方は、第1引数にクエリ失敗時のerrオブジェクト、第2引数に正常時の結果が入ります。よって、errオブジェクトの有無で失敗と成功の切り分けをします。
/createに対する処理は、まずリクエストbodyの中身をそのままPostモデルのコンストラクタに渡して、一致するフィールド(ここではtext)の値をセットしつつ生成しています。そしてsaveメソッドを呼んでコレクションに書き込んでいます。コールバック関数function(err)で、成功か失敗かを判断し、エラー時は前の画面に戻しています。前の画面のURLは、Referrerヘッダを利用してExpressが自動で処理しています。設定した文字列長確認のバリデートに不適合だった場合もここでエラーとなります。
動作確認
以上で実装は完了です。アプリケーションを起動して、
ブラウザから「http://localhost:3000/」にアクセスしてみましょう。
「New Entry」リンクからフォームにテキストを入力してPostしていくと、どんどんリストの項目が増えていくことがわかると思います。テキストを空でPostすると、コンソールに出力されるログでバリデートエラーが確認できます。
最後にMongoDBのシェルから実際のデータを確認してみます。mongodコマンドと同じ場所にあるmongoコマンド別のプロンプトから実行してください。まずshow dbsと命令すると、存在するデータベースの一覧が出ます。「use <データベース名>」で操作するデータベースを指定します。さらに「show collections」で、データベース内のコレクションの一覧が出ます。「db.<コレクション名>.find()」でコレクションの中身を表示します。
_idというのは、MongoDBのドキュメントにおける主キーのようなもので、未指定だと自動で割り当てられます。また特にセットしていない作成日時createdもスキーマに定義したとおり、追加時点での現在日時が入っています。
最後に
今回は、Mongooseを使ってMongoDBに、前回のアプリケーションを接続してみました。シンプルではありますが、非常に少ないコードで実装が終わってしまったと思います。この手軽さがNode.jsの魅力の1つだと筆者は思っています。次回以降は、様々なクラウドサービス上でこのアプリケーションをデプロイして動かしていきたいと思います。