Nodejsによるapiサーバ構築事例

32
node.jsによるAPIサーバ構築 h_mori 13418日木曜日

description

node.js presentation

Transcript of Nodejsによるapiサーバ構築事例

Page 1: Nodejsによるapiサーバ構築事例

node.jsによるAPIサーバ構築h_mori

13年4月18日木曜日

Page 2: Nodejsによるapiサーバ構築事例

自己紹介• 森 英寿(プログラマ)

hidetoshi.mori

@h_mori

SOICHA/TweetMe

ATND暦/生存連絡

13年4月18日木曜日

Page 3: Nodejsによるapiサーバ構築事例

背景

• iOSアプリから利用するAPIサーバ構築

• API認証基盤を作る

• PushNotificationを発行

13年4月18日木曜日

Page 4: Nodejsによるapiサーバ構築事例

node.jsを利用した経緯

• MongoDBのRESTオプションによる構築

• 後から認証基盤を追加実装

• 後からPushNotificationを実装

13年4月18日木曜日

Page 5: Nodejsによるapiサーバ構築事例

データモデル• DataList (トランザクション)

• User (アカウント情報) ※追加

• Device (端末情報) ※追加

• Group (ユーザカテゴリ) ※追加

13年4月18日木曜日

Page 6: Nodejsによるapiサーバ構築事例

サーバ構成

• MongoDB

• restify

• Mongoose

13年4月18日木曜日

Page 7: Nodejsによるapiサーバ構築事例

MongoDB?

• NoSQL

• ドキュメント指向DB(スキーマレス)

• where, like検索, 集計関数も可能

13年4月18日木曜日

Page 8: Nodejsによるapiサーバ構築事例

苦手なこと• トランザクション制御 (アトミック性は保証)

• リレーショナル、一意制約等

13年4月18日木曜日

Page 9: Nodejsによるapiサーバ構築事例

DB構造

• DBS > Collection > Object

(Database) (Scheme) (Record)

13年4月18日木曜日

Page 10: Nodejsによるapiサーバ構築事例

メリット

• 起動オプションにREST I/Fがある

• JSONとの親和性が高い

• WebAPI化しやすい

13年4月18日木曜日

Page 11: Nodejsによるapiサーバ構築事例

有用なケース

• トランザクション制御が不要

• 大量書き込みが想定される

• データの一意制約が不要

13年4月18日木曜日

Page 12: Nodejsによるapiサーバ構築事例

導入

• $ brew install mongodb

• $ port install mongodb

• mongodb.orgからDLして任意のフォルダに展開

13年4月18日木曜日

Page 13: Nodejsによるapiサーバ構築事例

DBサーバ起動

• $ ./bin/mongod -dbpath=db/ --rest

 ※RESTオプション付き

※28017ポートでWebAPIが起動

13年4月18日木曜日

Page 14: Nodejsによるapiサーバ構築事例

DBクライアント

• $ ./bin/mongo

GUI clientも存在するがメリットは薄い

13年4月18日木曜日

Page 15: Nodejsによるapiサーバ構築事例

URLアクセス

• curl 'http://localhost:28017/testdb/hoge'

• curl -d "{'user':'test'}" 'http://localhost:28017/testdb/hoge'

13年4月18日木曜日

Page 16: Nodejsによるapiサーバ構築事例

restify ?

• RESTに特化したnode.jsモジュール

• Expressを軽量化したようなもの

13年4月18日木曜日

Page 17: Nodejsによるapiサーバ構築事例

restifyの主な機能• Routing

• Header Parser / Error handler

• JSONP/JSON support

• GZIP support

• URL-encoder

• multipart form

13年4月18日木曜日

Page 18: Nodejsによるapiサーバ構築事例

restify導入

• $ npm install restify

• var restify = require('restify');

13年4月18日木曜日

Page 19: Nodejsによるapiサーバ構築事例

Routingvar 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日木曜日

Page 20: Nodejsによるapiサーバ構築事例

Mongoose ?• MongoDB用ドライバ

• Object Modeling Tool (O/Rマッパ)

• DBコネクションのバッファリング

• Validator、Defaults、Index等の定義可

13年4月18日木曜日

Page 21: Nodejsによるapiサーバ構築事例

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日木曜日

Page 22: Nodejsによるapiサーバ構築事例

Mongoose導入

• $ npm install mongoose

• var mongoose = require('mongoose');

13年4月18日木曜日

Page 23: Nodejsによるapiサーバ構築事例

cloud9 IDE

• ブラウザベースIDE

• クラウド上にプライベート領域を作れる(github,bitbucket,heroku等と連携)

• Node.js、PHP、Java、Ruby等をサポート

13年4月18日木曜日

Page 24: Nodejsによるapiサーバ構築事例

cloud9 IDE 導入

• ローカル環境にインストールも可能

• $ git clone https://github.com/ajaxorg/cloud9.git cloud9

• sudo ./cloud9/bin/cloud9.sh

13年4月18日木曜日

Page 25: Nodejsによるapiサーバ構築事例

cloud9 IDEの起動

• ./bin/cloud9.sh -w {workspace_dir} で起動

• http://localhost:3131 にアクセス

13年4月18日木曜日

Page 26: Nodejsによるapiサーバ構築事例

認証方式

• SSL + Basic認証 + sha1(solt)

13年4月18日木曜日

Page 27: Nodejsによるapiサーバ構築事例

restify.authorizationParser

{ scheme: <Basic|Signature|...>, credentials: <Undecoded value of header>, basic: { username: $user password: $password }}

• server.use(restify.authorizationParser());

• req.authorization オブジェクト

13年4月18日木曜日

Page 28: Nodejsによるapiサーバ構築事例

認証基盤の実装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日木曜日

Page 29: Nodejsによるapiサーバ構築事例

実装上の注意• I/O系関数は処理順序を保証しない

var user = User.findOne({email:req.params.email});user.password = req.params.password;user.save();res.send(user);

13年4月18日木曜日

Page 30: Nodejsによるapiサーバ構築事例

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日木曜日

Page 31: Nodejsによるapiサーバ構築事例

• 複雑な処理の同期が必要な場合は外部モジュールを検討する

実装上の注意

‣ async.js

‣ node-fibers

‣ flow-js

‣ step

13年4月18日木曜日

Page 32: Nodejsによるapiサーバ構築事例

実装して思ったこと

• 非同期処理が不要な場合node.jsは向かない (client, middlewareにロジックを置く場合は有)

• MongoDBと簡易JsonAPIは相性がいい

• node.jsと関連モジュールはまだまだ過渡期

13年4月18日木曜日