NodeでMongoDBをいじってみた
Node(Node.js)とMongoDBは相性がいいらしいので、試してみました。
とりあえず今回やってみたのはWebフレームワークにexpressを使い、
- InstagramのPopularを取ってきて
- それをMongoDBにそのまま突っ込んで
- あとはその内容を表示するだけ
という簡単なプログラムです。
ローカルだけではなく、サーバーはNodeのPaaSであるJoyent Node(no.de)にも試しにデプロイしてみました。
no.deはてっきりherokuのようなものだと思っていたのですが、SSHでログインしたりMongoDBをインストールしたり、なんてこともできるようです。
実際、今回のサンプルもno.de上にMongoDBをインストールして動かしてみました。
ごめんなさい、no.deの登録とかデプロイの仕方とかは省きます。
ライブラリのインストール
必要なライブラリをインストールします。
(no.deで公開する場合は、SSHでログインして同じように実行する必要があるのかな。
それともライブラリも./lib/あたりに置いて一緒にgit pushしちゃう方がいいのか、そのあたりの作法がわかりません。
今回はSSHでログインしてnpm installしました。)
($ brew install mongodb # Macでbrewな人はこれでMongoDBが入ります。)
$ npm install jade express instagram mongodb
ひな形の生成
まずはexpressコマンドで基本となるコードを生成します。
$ express testapp
メインになるスクリプトはapp.jsというファイル名なのですが、no.deにアップしたときにserver.jsというファイルじゃないと自動的に起動しないみたいなので、server.jsにリネームしました。
express?
expressはRubyのSinatraっぽいフレームワークです。
Sinatraで言う以下にあたるのが、
get '/' do
# do something...
end
expressではこうです。
app.get('/', function(req, res){
// do something...
});
今話題のCoffeeScriptで書くともっとSinatraに近くなると思いますが、
それをno.de上で動かすやり方が分からなかったのでとりあえずJavaScriptで書いています。
今回書いたコード(一部)
MongoDBとやり取りするコードは以下のようになりました。
どんどんコールバックでコードが右に伸びてしまいます。もっとかっこいい書き方をぜひ覚えたいところ。
server.js
/**
* Module dependencies.
*/
var express = require('express'),
instagram = require('instagram').createClient(
'Your-Client-Id', 'Your-Client-Secret'),
Db = require('mongodb').Db,
Server = require('mongodb').Server;
var app = module.exports = express.createServer();
var client = new Db('popular', new Server('127.0.0.1', 27017, {}));
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', function(req, res){
client.open(function(err, p_client){
client.collection('images', function(err, collection){
collection.find({}, {limit: 10}).toArray(function(err, images){
res.render('index', {
title: 'index',
images: images
});
});
});
});
});
app.get('/popular', function(req, res){
instagram.media.popular(function(images, error) {
client.open(function(err, p_client){
client.collection('images', function(err, collection){
collection.remove();
for (var i=0, l=images.length; i < l; i++) {
collection.insert(images[i]);
}
res.redirect('/');
});
});
});
});
// Only listen on $ node app.js
if (!module.parent) {
app.listen(process.env.PORT || 3000);
}
最低限のやり方はなんとなくわかったので、実際にひとつアプリを作ってみています。
せっかくなのでCoffeeScriptで書きたいのでもうちょっと調べてみたいと思います。