Node.js+jQuery Mobile+MongoDBでCRUDアプリケーションを作る(その3)
Node.js, jQuery Mobile, MongoDBを使ったRESTfulなCRUDアプリケーションが一通りできあがったので、まとめを書こうと思います。ユーザ認証やバリデーション、ページングなど実際に必要な処理は全くありませんが、とりあえずCRUDの骨組みとしては完成です。
これまでのエントリーは以下です(最新はここから少し変更を加えています)。
- Node.js+jQuery Mobile+MongoDBでCRUDアプリケーションを作る(その1) - ken’s room 〜技術探求のメモ〜
- jQuery MobileでCRUDアプリケーションのフロントを作って学んだ5つのこと(Node.js+jQuery Mobile+MongoDBでCRUDアプリケーションを作る(その2)) - ken’s room 〜技術探求のメモ〜
アプリケーションはnode-ninja上のこちらで動かしています。
また、このアプリケーションのソースは以下で公開しています。
RESTfulなAPIのURI
'memo'に対するgetを初期表示にしたため、一覧の取得APIを'memo/list'のgetにしました。
- app.get 'memo/list' MemoのRead(一覧取得)
- app.get 'memo/:id' MemoのRead(id指定)
- app.post 'memo' MemoのCreate
- app.put 'memo/:id' MemoのUpdate
- app.del 'memo/:id' MemoのDelete
views/layout.jade
!!! 5 html head title='Memo' meta(name='viewport', content='width=device-width, initial-scale=1') meta(name='apple-mobile-web-app-capable', content='yes') meta(name='apple-mobile-web-app-status-bar-style', content='black') link(rel='stylesheet', href='http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css') script(src='http://code.jquery.com/jquery-1.6.4.min.js') script(src='http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js') body!= body
views/index.jade(viewページ抜粋)
div#view(data-role='page') div(data-role='header') a(data-rel='back', data-icon='back', data-derection='reverse') Back h1 Memo View a(href='#add', data-icon='plus') Add div(data-role='content') div(data-role='filedcontain') label(for='memo-view') Memo p#memo-view div.ui-bar(data-role='footer', data-position='fixed') div(data-role='controlgroup', data-type='horizontal') a(href='#edit', data-icon='gear', data-transition='flip') Edit a(href='#confirm-dialog', data-icon='delete', data-rel='dialog') Delete
- footerを下部に固定するように変更
- data-position='fixed'を指定
- class ui-headerを指定してボタンの配置を制御していましたが、fixedが有効にならないので変更
- headerについては、fixedを指定しない方が画面遷移時に安定します。
- footerのボタンは水平方向にグループ化
- Deleteボタン押下時にはConfirmダイアログを表示するように変更
views/index.jade(viewページ表示前処理抜粋)
$("#view").bind('pagebeforeshow', function(e, ui) { $("#memo-view").html(' '); $.get( 'memo/' + mstore.selectedid , function(data) { $("#memo-view").html(data.content); } ); });
- イベントをpageshowからpagebeforeshowに変更
app.js(RESTful API部抜粋)
app.get('/memo', function(req, res) { console.log("index"); Memo.find({}, function(err, data) { if(err) return next(err); res.render('index', { memos: data }); }); }); app.get('/memo/list', function(req, res, next) { console.log("get memos"); Memo.find({}, function(err, data) { if(err) return next(err); res.json(data); }); }); app.get('/memo/:id', function(req, res, next) { console.log("get memo : " + req.params.id); Memo.findById({ _id : ObjectId(req.params.id)}, function(err, data) { if(err) return next(err); res.json(data); }); }); app.post('/memo', function(req, res, next) { console.log("post memo : " + req.body.content); var memo = new Memo(); memo.content = req.body.content; memo.save(function(err) { if(err) return next(err); res.json({ message : 'Success!'}); }); }); app.put('/memo/:id', function(req, res, next) { console.log("put memo : " + req.params.id); Memo.update( { _id : ObjectId(req.params.id) } , { content : req.body.content, date : new Date() } , { upsert : false, multi : false } , function(err) { if(err) return next(err); res.json({ message : 'Success!'}); }); }); app.del('/memo/:id', function(req, res, next) { console.log("delete memo : " + req.params.id); Memo.findById({ _id : ObjectId(req.params.id)}, function(err, data) { if(err) return next(err); data.remove(function(err) { console.log("memo remove!"); res.json({ message : 'Success!'}); }); }); });
- 'memo'に対するgetは、取得したデータをindex.jadeにレンダリングして初期ページとして返します。
- updateのupsertは対象がない場合にinsertするかどうかのオプション指定
- updateのmultiは条件にマッチするデータを複数更新するかどうかのオプション指定
最後に
Node.js, MongoDB, jQuery Mobileを使ってRESTfulなCRUDアプリを一通り作ってみて、いろいろ学ぶことができました。やはり手を動かして作ってみるのが一番理解が進みますね。
一番ハマったのはjQuery Mobile。少しの条件の違いで挙動が変わってくるので、検証してパターンを作っていくことが必要だと感じました。まだまだ動きもモッサリしていますしね。凝ったエフェクトではなく、とことんスピードに拘ったモバイル系のフロントフレームワークが出てきたりすると面白いかもしれませんね。
Node.js+MongoDBは相性がよく、シンプルに書けるのがよいです(まぁ、たいした処理は組んでいませんが)。