More Related Content
Similar to Nodejsによるapiサーバ構築事例
Similar to Nodejsによるapiサーバ構築事例(20)
More from Hidetoshi Mori(20)
Nodejsによるapiサーバ構築事例
- 2. 自己紹介
• 森 英寿(プログラマ)
hidetoshi.mori
@h_mori
SOICHA/TweetMe
ATND暦/生存連絡
13年4月18日木曜日
- 3. 背景
• iOSアプリから利用するAPIサーバ構築
• API認証基盤を作る
• PushNotificationを発行
13年4月18日木曜日
- 4. node.jsを利用した経緯
• MongoDBのRESTオプションによる構築
• 後から認証基盤を追加実装
• 後からPushNotificationを実装
13年4月18日木曜日
- 5. データモデル
• DataList (トランザクション)
• User (アカウント情報) ※追加
• Device (端末情報) ※追加
• Group (ユーザカテゴリ) ※追加
13年4月18日木曜日
- 6. サーバ構成
• MongoDB
• restify
• Mongoose
13年4月18日木曜日
- 7. MongoDB?
• NoSQL
• ドキュメント指向DB(スキーマレス)
• where, like検索, 集計関数も可能
13年4月18日木曜日
- 8. 苦手なこと
• トランザクション制御
(アトミック性は保証)
• リレーショナル、一意制約等
13年4月18日木曜日
- 9. DB構造
• DBS > Collection > Object
(Database) (Scheme) (Record)
13年4月18日木曜日
- 10. メリット
• 起動オプションにREST I/Fがある
• JSONとの親和性が高い
• WebAPI化しやすい
13年4月18日木曜日
- 11. 有用なケース
• トランザクション制御が不要
• 大量書き込みが想定される
• データの一意制約が不要
13年4月18日木曜日
- 12. 導入
• $ brew install mongodb
• $ port install mongodb
• mongodb.orgからDLして任意のフォルダに展開
13年4月18日木曜日
- 13. DBサーバ起動
• $ ./bin/mongod -dbpath=db/ --rest
※RESTオプション付き
※28017ポートでWebAPIが起動
13年4月18日木曜日
- 14. DBクライアント
• $ ./bin/mongo
GUI clientも存在するがメリットは薄い
13年4月18日木曜日
- 15. URLアクセス
• curl 'http://localhost:28017/testdb/hoge'
• curl -d "{'user':'test'}" 'http://localhost:28017/testdb/hoge'
13年4月18日木曜日
- 16. restify ?
• RESTに特化したnode.jsモジュール
• Expressを軽量化したようなもの
13年4月18日木曜日
- 17. restifyの主な機能
• Routing
• Header Parser / Error handler
• JSONP/JSON support
• GZIP support
• URL-encoder
• multipart form
13年4月18日木曜日
- 18. restify導入
• $ npm install restify
• var restify = require('restify');
13年4月18日木曜日
- 19. Routing
var restify = require('restify');
var server = restify.createServer();
server.use(restify.queryParser());
function send(req, res, next) {
res.send('hello ' + req.params.name);
return next();
}
server.post('/hello', function create(req, res, next) {
res.send(201, Math.random().toString(36).substr(3, 8));
return next();
});
server.get('/hello/:name', send);
server.head('/hello/:name', send);
server.del('hello/:name', function rm(req, res, next) {
res.send(204);
return next();
});
13年4月18日木曜日
- 20. Mongoose ?
• MongoDB用ドライバ
• Object Modeling Tool (O/Rマッパ)
• DBコネクションのバッファリング
• Validator、Defaults、Index等の定義可
13年4月18日木曜日
- 21. Mongooseの使用例
var UserSchema = new mongoose.Schema({
email:{
type: String,
unique: true,
index: true
},
password:String,
created_at:{type: Date, default: Date.now},
updated_at:{type: Date, default: Date.now}
});
UserSchema.pre('save', function(next) {
this.updated_at = Date.now();
next();
});
var User = mongoose.model('user', UserSchema);
13年4月18日木曜日
- 22. Mongoose導入
• $ npm install mongoose
• var mongoose = require('mongoose');
13年4月18日木曜日
- 23. cloud9 IDE
• ブラウザベースIDE
• クラウド上にプライベート領域を作れる
(github,bitbucket,heroku等と連携)
• Node.js、PHP、Java、Ruby等をサポート
13年4月18日木曜日
- 24. cloud9 IDE 導入
• ローカル環境にインストールも可能
• $ git clone https://github.com/ajaxorg/
cloud9.git cloud9
• sudo ./cloud9/bin/cloud9.sh
13年4月18日木曜日
- 25. cloud9 IDEの起動
• ./bin/cloud9.sh -w {workspace_dir} で起動
• http://localhost:3131 にアクセス
13年4月18日木曜日
- 26. 認証方式
• SSL + Basic認証 + sha1(solt)
13年4月18日木曜日
- 27. restify.authorizationParser
• server.use(restify.authorizationParser());
• req.authorization オブジェクト
{
scheme: <Basic|Signature|...>,
credentials: <Undecoded value of header>,
basic: {
username: $user
password: $password
}
}
13年4月18日木曜日
- 28. 認証基盤の実装
server.use(function authenticate(req, res, next) {
if (!req.authorization.basic) {
res.header('WWW-Authenticate', 'Basic realm=""');
res.send(401);
return next(false);
}
User.findOne({email:req.username}, function (err, user) {
if (err) { return next(err); }
if (!user && user.password !== req.authorization.basic.password) {
return next(new restify.NotAuthorizedError());
}
return next();
});
});
13年4月18日木曜日
- 29. 実装上の注意
• I/O系関数は処理順序を保証しない
var user = User.findOne({email:req.params.email});
user.password = req.params.password;
user.save();
res.send(user);
13年4月18日木曜日
- 30. 実装上の注意
• 必ずコールバックにて処理
User.findOne({email:req.params.email}, function(err, user) {
user.password = req.params.password;
user.save(function(arr, data)) {
res.send(data);
});
}
13年4月18日木曜日
- 31. 実装上の注意
• 複雑な処理の同期が必要な場合は外部
モジュールを検討する
‣ async.js
‣ node-fibers
‣ flow-js
‣ step
13年4月18日木曜日
- 32. 実装して思ったこと
• 非同期処理が不要な場合node.jsは向かない
(client, middlewareにロジックを置く場合は有)
• MongoDBと簡易JsonAPIは相性がいい
• node.jsと関連モジュールはまだまだ過渡期
13年4月18日木曜日