Node.js(restify) + MongoDB(mongoose) ã§APIãµã¼ãã¤ãã£ã¦Herokuã§ãããã¤ããã¾ã§
å
æ¥ãããããªãªã¼ã¹ããã¢ããªããé段ç»ããã§ã¯ããã é段ãä¸ãã ãã®ã¯ã½ã¢ããªã¨æããããä»ã®ã¦ã¼ã¶ã¼ã®ä½ç½®ã¾ã§æ¥ããããéã£ã¦ã¿ãããä¸çªä¸ã«ãã人ã®æ®µæ°ãã¨ã£ã¦ããããå½±ã§ã³ã½ã³ã½ãã£ã¦ããã¾ããï¼ã¯ã½ãªã®ã«ã¯å¤ããã¾ããããï¼
https://itunes.apple.com/jp/app/o-jie-duan-dengri-zuo-rino/id956171342?mt=8&uo=4&at=10l8JW&ct=hatenablog
ã³ã½ã³ã½ããããã«ãµã¼ãã¼ãèªä½ãã¾ããã
ãµã¼ãã¼å´ã§ãã£ã¦ããã¨ä¾
- ã¦ã¼ã¶ã¼ç»é²
- èªåã®ã¹ã³ã¢ãæ´æ°ãã
- 1ä½ã®ã¹ã³ã¢ãåå¾ãã
- èªåã1ä½ãã©ããè¿ã
- èªåã®ã¹ã³ã¢ã«ä¸çªè¿ãã¦ã¼ã¶ã®æ å ±ãè¿ãï¼âã¦ã¼ã¶ã®ã¹ã³ã¢ã¾ã§å°éãããããéãå®è¡ï¼
ã¢ããªããã¯HTTPãªã¯ã¨ã¹ãæããJSONå½¢å¼ã§ã¬ã¹ãåå¾ãã¦ã¬ã¹ã«ãã£ã¦æç»ãå¤ããããã¾ãã
ãããªAPIãµã¼ãã¼çãªãã®ãNode.jsãã¤ãã£ã¦å®è£
ãã¾ããã
åå¿é²ã§ãµã¼ãã¼ä½æããHerokuã¸ã®ãããã¤ã¾ã§ããæ¹ãæ®ãã¾ãã
ç°å¢
- Mac OS 10.10.2
- Node.js v0.10.25
- MongoDB 2.6.7
äºåã«åå¼·ãããã¨
æ¬ä»¶ã®è¨äºã¨ç´æ¥é¢ä¿ãªãã®ã§ãå¥è¨äºã«ãã¾ãã
âãã¡ã
Node.js + MongoDBでAPIサーバつくるまでに勉強したこと - イッツァハローワールド
ãªãã§ããããRestifyã¤ãã£ããã
ã°ã°ã£ãããREST Webãµã¼ãã¹ã®æ§ç¯ã«ç¹åãããã¬ã¼ã ã¯ã¼ã¯ãã£ã¦åºã¦ããã®ã§ãããããã¤ãã£ã¦ã¿ãï¼ã£ã¦æãã§ä½¿ãã¾ããã
ä»åã¤ãããããªç°¡åãªãããªãExpressã§ååã«æãã¾ããï¼ä½ã£ãå¾ã§ãããã¾ããwï¼
ãã¨ãè±èªã®ããã¥ã¡ã³ãã§åè¦å «è¦ãã¦ã¿ããã£ãã£ã¦ããã®ãã¡ããã£ã¨ããã¾ãã
ä»åä½ããã®ã®ä»æ§
- ã¦ã¼ã¶ã¼ãã¨ã«ä»¥ä¸ã®ãã¼ã¿ãæã¤
- ã¦ã¼ã¶ã¼IDï¼idï¼
- ã¹ã³ã¢ï¼scoreï¼
- ãµã¼ãã¼ã¯APIã§CRUDãªåãããã
- ã¬ã¹ãã³ã¹ã¯JSONã§è¿ã
ãã¨ã¯é©å½ã«ã
ã¾ãã¯Restifyãã¤ãã£ã¦ç°¡åãªãµã³ãã«ã³ã¼ããã¤ãã
Node.jså ¥ããã¨ããã¨ãã¯å²æãã¾ãã
restifyãã¤ã³ã¹ãã¼ã«
$ npm install restify
ãµã³ãã«ã³ã¼ãå®è£
以ä¸ã¯ãhttp://0.0.0.0:8080/hello_worldã«ã¢ã¯ã»ã¹ããã¨message : Hello World!ã£ã¦å 容ã®JSONãè¿ãä¾ã
// sample.js var restify = require('restify'); // ãµã¼ãã¼çæ var server = restify.createServer(); // http://0.0.0.0:8080/hello_worldã«GETãªã¯ã¨ã¹ãããã¨ãã®å¦ç function helloWorld(req, res, next){ // ã¬ã¹ãã³ã¹ res.send({message: 'Hello World!'}); } // ãã¹ã¨é¢æ°ã®ç´ä»ã // âã¯http://0.0.0.0:8080/hello_worldã«GETãªã¯ã¨ã¹ããããhelloWorldé¢æ°ãå®è¡ server.get('/hello_world', helloWorld); server.listen((8080), function() { console.log('%s listening at %s', server.name, server.url); });
å®è¡
ã³ãã³ãå©ãã¦å®è¡ã
$ node sample.js
http://0.0.0.0:8080/hello_worldãéãã¦ã¿ã
ã§ããããããªãããã§ãAPIãã¨ã«é¢æ°ã¨ãé¢æ°ã¨ãã¹ã¨ã®ç´ä»ããå®ç¾©ããã°ããã¨ç°¡åã«ä½ãã¾ãã
以ä¸ã¯mongooseãè½ã¨ãã¦ãMongoDBãã¤ãã£ã¦CRUDãã¾ãã
å®éã®APIãµã¼ãå®è£ ãã£ã¦ã¿ã
ã¾ãMongoDB, mongooseå ¥ãã
$ npm install mongodb $ npm install mongoose
ã³ã¼ã
// sample.js var restify = require('restify'); var server = restify.createServer(); // ãµã¼ãã¼çæ server.use(restify.bodyParser()); // POSTãã¼ã¿ããã¼ã¹ããã²ã¨ãç»é² server.use(restify.queryParser()); // ã¯ã¨ãªããã¼ã¹ããã²ã¨ãç»é² var mongoose = require('mongoose'); var uristring = 'mongodb://localhost/'; var db = mongoose.connect(uristring); var Schema = mongoose.Schema; // ã¹ãã¼ãã®å®ç¾© var userSchema = new Schema({ score: Number, }); // ã¢ãã«ãçæ mongoose.model('user', userSchema); var User = mongoose.model('user'); // Create function createUser(req, res, next){ var user = new User(); // ã³ã¬ã¯ã·ã§ã³ãä½æ user.score = 0; // ã¤ãã£ãã³ã¬ã¯ã·ã§ã³ãä¿å user.save(function(err, data){ res.send({function:'Create', status: 'OK', id: data._id}); }); } // Read function getUsers(req, res, next){ User.find(function(arr, data){ // ãã¹ã¦ã®ã³ã¬ã¯ã·ã§ã³ã®æ å ±ãè¿ã res.send(data); }); } // Delete function deleteUser(req, res, next){ // å ¥åãããIDã®ã³ã¬ã¯ã·ã§ã³ãåé¤ãã User.remove({ _id: req.params.id }, function(err){ res.send({function:'Delete', status: 'OK'}) }); return next(); } function updateScore(req, res, next){ // IDãæ¤ç´¢ User.findById(req.params.id, function (err, data) { // ã¨ã©ã¼å¦ç if (err) { res.send({function:'Update', status:'NG', reason: 'User not found.'}); return next(); }; // å ¥åãã©ã¡ã¼ã¿ç°å¸¸ if (req.params.id == '' || req.params.id === undefined ) { res.send({function:'Update', status:'NG', reason: 'User not found.'}); return next(); }; if (req.params.score == '' || req.params.score == 0) { res.send({function:'Update', status:'NG', reason: 'Score is invalid.'}); return next(); }; // å ¥åãããIDã®ã¹ã³ã¢ãå ¥åããããã®ã«å¤æ´ãã User.update({ _id: req.params.id }, { $set: {score: req.params.score} }, { upsert: false, multi: true }, function(err) { if (err) { res.send({function:'Update', status:'NG', reason: 'Update faild'}); return next(); }; res.send({function:'Update', status:'OK'}); }); }); } server.get('/get_users', getUsers); server.post('/delete_user', deleteUser); server.put('/update_score',updateScore); server.post('/create_user',createUser); server.listen((8080), function() { console.log('%s listening at %s', server.name, server.url); });
åä½ç¢ºèª
å®éã«åAPIå¼ãã ãã©ããªã¬ã¹ãã³ã¹ãè¿ããè¦ã¦ã¿ã¾ãã
åä½ãè¦ãããã«Chromeã®ã¨ã¯ã¹ãã³ã·ã§ã³ã®Advanced REST Clientãã¤ããã¾ãã
create(create_user)
ã¾ãã¯ã³ã¬ã¯ã·ã§ã³ãçæãã¦ã¿ã¾ãã
Advanced REST Clientãèµ·åããReqestã¿ããéãã¾ãã
POSTãé¸æãããã¹ãå
¥åãã¾ãã
å
¥åããããSendããã¿ã³ãæ¼ä¸ããã¨ã¬ã¹ãã³ã¹ã帰ã£ã¦ãã¾ãã
ããã§ã²ã¨ã¤ã³ã¬ã¯ã·ã§ã³ãã§ãã¾ããã
get(get_users)
ã¤ãã«çæããã³ã¬ã¯ã·ã§ã³ãåå¾ãã¾ãã
ããã©ã¯GETãé¸æãã¾ãã
ãSendããã¿ã³æ¼ä¸ã§ãå
ã»ã©ä½ã£ãã³ã¬ã¯ã·ã§ã³ãåå¾ã§ãã¾ãã
update(update_score)
ã³ã¬ã¯ã·ã§ã³ã®scoreãæ´æ°ãã¾ãã
ããã©ã¯PUTãé¸æããæ´æ°ããid, æ´æ°å¾ã®scoreãå
¥åãã¾ãã
ãããã«1234ãå
¥ãã¦ã¿ã¾ãã
ãSendããã¿ã³æ¼ä¸ã§ãæ´æ°å®äºã帰ã£ã¦ãã¾ãã
å度GETãã¦ã¹ã³ã¢ãè¦ã¦ã¿ã¾ãã
æ´æ°ããã¾ããã
å
¥åã¨ã©ã¼ç¨ã®ã³ã¼ããæ¸ãã¦ã¿ãã®ã§åä½ã確èªãã¦ã¿ã¾ãã
ãããã«ãidãåå¨ããªãå¤ã«æ¸ãæãã¦ãSendããã¿ã³ãæ¼ä¸ããã¨
ã¨ã©ã¼ã帰ã£ã¦ãã¾ããã
delete(delete_user)
ã¤ãã£ãã³ã¬ã¯ã·ã§ã³ã®åé¤ãè¡ãã¾ãã
POSTãé¸æãã¦ãåé¤ãããã³ã¬ã¯ã·ã§ã³ã®idãå
¥åãã¾ãã
ãSendããã¿ã³æ¼ä¸ã§ã³ã¬ã¯ã·ã§ã³ãåé¤ããã¾ãã
GETãã¦ç¢ºããã¦ã¿ã¾ãã
DBã空ã«ãªã£ã¦ã¾ããã
ãã£ãï¼
Herokuã¸ãããã¤ãã¦ã¿ã
ããã¾ã§ã§å®è£ ã¯ã»ã¼çµãããHerokuã¸ãããã¤ãã¦ã¿ã¾ãã
Heroku toolbeldï¼Herokuæ¨å¥¨ï¼ã®ã¤ã³ã¹ãã¼ã«
Herokuã«ãã°ã¤ã³
$ heroku login
Herokuã¸ç»é²ããæã®ã¡ã¼ã«ã¢ãã¬ã¹ã¨ãã¹ã¯ã¼ããèãããã®ã§å
¥åãã¾ãã
package.jsonä½æ
é©å½ã«å ¥åãã¾ãã
$ npm init
ä»åä½æããã®ã¯ãããªæãã§ãã
{ "name": "sample", "version": "0.0.1", "description": "sample api server", "main": "sample.js", "dependencies": { "mongodb": "~1.4.33", "mongoose": "~3.8.24", "restify": "~2.8.5" }, "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "hanamiju", "license": "MIT" }
Herokuç¨ã®Procfileãä½æ
web: node sample
ããã¤ã«Herokuããå¼ã¶jsãã¡ã¤ã«ãè¨è¼ãã¾ããæ¡å¼µåã¯ãããªãã§ãã
Herokuã®ããã¸ã§ã¯ãä½æ
ããã¸ã§ã¯ããçæãããä»åã¯apiserverkunnã¨ããååã§ç»é²ãã¾ããã
$ heroku create apiserverkunn
MongoLabãããã
å
ã»ã©ã¾ã§ã¯ãã¼ã«ã«ç°å¢ã«MongoDBãæ§ç¯ãã¦ã¾ãããããããã¤ã«ãããMongoLabãå
¥ãã¾ãã
MongoLabã¯Herokuã®ã¢ããªã³ã®ã²ã¨ã¤ã§ãHerokuã§MongoDBã496MBã¾ã§ç¡æã§ä½¿ãã¾ããæé«ã
ã¨ããããã§ã¢ããªã³ãæ¢ãã¾ããMongoã¨ãæ¤ç´¢ã¯ã¼ãã§å
¥ããã°ã§ã¦ãã¾ãã
ããã¤ã®freeãã©ã³ãapiserverkunnã«é©ç¨ããã¾ãã
ä¸è¨ã®ããã«ãã©ã¦ã¶ããã§ããããã
$ heroku addons:add mongolab
ã§ããªã¼ã©ã¤ã
sample.jsãã¡ã¤ã«ãä¿®æ£ããã
sample.jsã¯ãã®ã¾ã¾ã ã¨ãã¼ã«ã«ç°å¢ã§ããåããªãã®ã§ããã¡ã¤ã«ãä¸é¨ä¿®æ£ãã¾ãã
ã¾ãã¯MongoDBã¨ã®æ¥ç¶æã®ãã¹
var uristring = 'mongodb://localhost/'; // å¤æ´å var uristring = process.env.MONGOLAB_URI || 'mongodb://localhost/'; // å¤æ´å¾
ããã§ãprocess.env.MONGOLAB_URIã«æ¥ç¶ããåå¨ããªãå ´åã¯mongodb://localhost/ã«æ¥ç¶ãããã
ã¤ã¾ãããã¼ã«ã«ã¨æ¬çªã§ã³ã¼ããæ¹å¤ããã«æ¸ãã¨ãããã¨ã
ã¤ãã«ãµã¼ãã¼å¦çéå§æ
server.listen((8080), function() { // å¤æ´å server.listen((process.env.PORT || 8080), function() { // å¤æ´å¾
ç°¡åã«å®è¡ç°å¢æ¯ã®è¨å®ã§ã¢ããªã±ã¼ã·ã§ã³ãå®è¡ãããã¨ãã§ãã¾ãã
Herokuã¸ãããã¤
$ git init $ git add . $ git commit -m "hoge" $ git push heroku master
çµæãè¦ã¦ã¿ã
ãããããcreateãã¨ãã¦ãããgetãã¦ã¬ã¹ãã³ã¹ãè¦ã¦ã¿ã¾ãã
ã¡ããã¨è¡¨ç¤ºããã¾ãããã°ãããï¼