koaとangularjsとMongoDBでWebAppsを作る
さて、Node.js 日本ユーザグループの新代表になりました。@yosuke_furukawa です。
改めてブログで挨拶します、と言いましたが書きかけのエントリがお正月から眠っているので、一旦溜まったブログを書いてから記述します。
最近やっぱりkoaにはまってて、一個koaでWebアプリを作ってみようかなと思い、Twitterライクな掲示板を作ってみました。
アプリ : http://angular-koa.herokuapp.com/#/
GitHub : yosuke-furukawa/angular-koa · GitHub
koaでRESTFulなapiサーバを作る
一旦koaでRESTFulなapiサーバを作ります、自分で作ってもすごく簡単なのですが、ここでは、api-boilerplate を使いましょう。
api-boilerplateの中身
api-boilerplateはTJがサンプルとして作っているリポジトリで、koaでapiサーバを作る上では格好の教材。面白いので少しだけ紹介します。
api-boilerplateをinstallする
つってもcloneするだけ。まだkoaにはgeneratorがないので、yeomanでgeneratorも作ってみようかと思ってますが、ひとまずcloneしてください。
$ git clone https://github.com/koajs/api-boilerplate.git
api-boilerplateに移動したら、以下の要領で起動することができます。
※ 起動にはredisが必要です、redisがない場合は、インストールして起動しておいてください。
$ node --harmony ./bin/api
デフォルトは4000番ポートで起動するので、起動後にcurl等を使うと動きがわかると思います。
$ curl http://localhost:4000/users { "tobi": { "name": "tobi", "age": 3, "species": "ferret" }, "loki": { "name": "loki", "age": 2, "species": "ferret" }, "jane": { "name": "jane", "age": 7, "species": "ferret" } } $ curl http://localhost:4000/users/tobi { "name": "tobi", "age": 3, "species": "ferret" }
api-boilerplateのライブラリ
api-boilerplateでは下記のライブラリを使っています。
- koa-response-time, koa-logger (レスポンス記録用)
- koa-ratelimit (リクエストの処理回数が多くなった時に429, Too Many Requestsを返して一時的にリクエストを受け付けなくするライブラリ、要は人大杉機能、ここでRedisを利用する)
- koa-compress (レスポンス圧縮用)
- koa-router (HTTP methodに対してRouterを提供するライブラリ、RESTFulな処理ができる)
koa-routerが少し特殊で、 各種HTTP methodに対して以下のようにメソッドをmappingしています。
app.resource('users', { // GET /users index: function *(next) { }, // GET /users/new new: function *(next) { }, // POST /users create: function *(next) { }, // GET /users/:id show: function *(next) { }, // GET /users/:id/edit edit: function *(next) { }, // PUT /users/:id update: function *(next) { }, // DELETE /users/:id destroy: function *(next) { } });
api フォルダ以下に下記のような構成を持っています。
api ├── stats │ ├── config.json -> ルーティングのマッピングを定義することが可能 │ ├── index.js -> いわゆるcontroller │ └── test.js -> controllerのテストスクリプト
MongoDBでデータストアを設定する。
koaでMongoDBを扱う場合、coベースのmongoドライバーを使う必要があります。今回はco-monkを使いました。
実装例:
var monk = require('monk'); var monkWrapper = require('co-monk'); var db = process.env.MONGOLAB_URI ? monk(process.env.MONGOLAB_URI) : monk('localhost:27017/tweets'); var tweets = monkWrapper(db.get('tweets')); /** * GET tweets. */ exports.index = function *(){ var query = this.query; var lastId = Infinity; if (query.lastId) lastId = +query.lastId; var result = yield tweets.find({_id : { $lt : lastId}}, { sort : {_id : -1}, limit : listsNum }); this.body = result; };
yieldで結果を取得できる点、monkWrapperでdbを取得している点が特徴的ですね。
Angularjsでクライアントサイドのビューを作る
koaでJSONを返すAPIサーバを作成したので、ビュー側はkoaのテンプレートエンジンではなく、Angularjsでビューを作りましょう。
細かい説明は省きますが、ハマったところとライブラリを紹介します。
angularはyeomanのgeneratorが存在するので、generator-angularで作ればいいかーとか思ってたんですが、generator-angularはNode v0.11をサポートしていません。というか、gruntもサポートしてません。
無理矢理動かそうとすると、エラーになるので、下記のpull requestを参考に修正してください。
Update bower version by yosuke-furukawa · Pull Request #43 · btford/grunt-google-cdn · GitHub
Angularjsの依存ライブラリ
angularjsでは、ngResourceやngRouteなどの標準モジュール以外に以下のライブラリを利用するようにしました。
- infinite-scroll (いわゆる無限スクロールをサポートするライブラリ)
bower 対応しているので以下の方法で入ります。
$ bower install nginfinitescroll --save
コードはこの辺りを参考にしてください。
https://github.com/yosuke-furukawa/angular-koa/blob/master/app/scripts/controllers/main.js#L15-L28
まとめ
- koa, mongodb, angularjsでwebアプリを作ってみました。
- koaでRESTFulなサーバ作るのであればapi-boilerplateが参考になります
- koaでデータストアを作る場合、coベースのライブラリを利用する必要があります。今回はco-monkを利用しました。
- ビューはangularjsで作りました。そこまで大したことはしてませんが、無限スクロールをサポートするinfinite-scrollを使ってみました。
感想
Koaで色々作るとライブラリ間が疎なので、色んな物を試せてすごく面白いです。
次はcoとthunkifyでcoベースのライブラリも作ってみようかと思います。