Edited at

Node.js+Express+MongoDBでREST APIをつくる

More than 1 year has passed since last update.


Node.js

1.http://nodejs.org からNode.jsをインストールする

2.マニュアル

https://nodejs.org/api/


Express


動かす

http://expressjs.com/en/starter/generator.html

に従う。以下、簡単な手順。

1.インストール

$ npm install express-generator -g

2.Express application generator実行

$ express restapi; cd restapi; npm install

3.動かす

Mac

$ DEBUG=restapi:* npm start

Windows

> set DEBUG=restapi:* & npm start

4.ブラウザで確認する

http://localhost:3000

5.マニュアル

http://expressjs.com/4x/api.html


変更したときにオートリロードするようにnode-devをいれる

1.インストール

$ npm install -g node-dev

2.動かす

$ node-dev bin/www


MongoDB


インストール

以下からインストール。

http://www.mongodb.org/

macの場合はbrewからインストールするといいかも。

brew install mongodb

brewでインストールすると、次のメッセージがでるので、lnとlaunchctlコマンドをうつ。

(または、mongodコマンド)

To have launchd start mongodb at login:

ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents
Then to load mongodb now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
Or, if you don't want/need launchctl, you can just run:
mongod --config /usr/local/etc/mongod.conf


コマンド操作

1.起動

mongo

2.以下のコマンドで操作(詳細は公式サイトで確認)

https://docs.mongodb.org/manual/core/crud-introduction/

コマンド
説明

show dbs
データベース一覧表示

use [db_name]
データベース切り替え。ないときは最初の挿入時に作成される。

db
現在のデータベース表示

help
ヘルプ

db.getCollectionNames()
すべてのコレクションのリスト表示

db.[collection_name]
コレクション

db.[collection_name].insert({key:value})
挿入

db.[collection_name].find()
検索(SELECT)

db.[collection_name].find({key:value})
条件検索

db.[collection_name].update({key1:value1}, {key2:value2})
キーkey1の値がvalue1であるドキュメントのキーkey2の値をvalue2に更新

db.[collection_name].update({key1:value1}, {$set:{key2:value2}})
キーkey1の値がvalue1であるドキュメントのキーkey2の値をvalue2に更新(値がないときは追加)

db.[collection_name].remove({key:value})
条件削除

3.終了

exit


Node+Expressから接続


MongoDB Driverのインストール

1.インストール

npm install --save mongodb

2.マニュアル

インターネットの情報は新旧混ざってるので、バージョンには注意。

http://mongodb.github.io/node-mongodb-native/2.1/api/


mongodb操作用のmongo.jsを追加

ここの書き方は、バージョンに依存する部分が多く、インターネットには新旧の情報が混じっているので注意。

ここでは、2.1のドキュメントに準拠して書いている。

http://mongodb.github.io/node-mongodb-native/2.1/api


mongo.js

/**

* node-mongodbのドキュメント
* http://mongodb.github.io/node-mongodb-native/2.1/
*/

var db;
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');

// Connection URL
var url = 'mongodb://localhost:27017/Sakepedia';

// Use connect method to connect to the Server
MongoClient.connect(url, function(err, mongodb) {
assert.equal(null, err);
console.log("Connected correctly to server");
db = mongodb;
});

var collection = function( name ) {
return db.collection( name );
}

module.exports = collection;



ルーティング

1.app.jsを変更


app.js

(前略)

// var routes = require('./routes/index');
// var users = require('./routes/users');
var restapi = require( './routes/restapi' );

(中略)

// app.use('/', routes);
// app.use('/users', users);
app.use( '/api', restapi );

(後略)


2.restapi.jsの追加


  • routes.jsをシンプルにしたいので、var collection = require( '../mongo' );部分でMongoDB用ファイルは別ファイルにしている

  • Cross Origin制約のためにrouter.allですべてのメソッドにheaderを設定している(もちろん他のドメインに使わせたくない場合は不要)

  • パスの:id部分はパラメーターとしてrequest.params.idのように扱える

  • idを扱うために、var ObjectID = require('mongodb').ObjectID;部分でObjectIDをインポートしている


routes/restapi.js

var express = require( 'express' );

var router = express.Router();
var ObjectID = require('mongodb').ObjectID;
// MongoDB用ファイルを指定
var collection = require( '../mongo' );
var COL = 'restapi';

// For Cross Origin
router.all( '/*', function ( req, res, next ) {
res.contentType( 'json' );
res.header( 'Access-Control-Allow-Origin', '*' );
next();
} );

// GET find
router.get( '/', function ( req, res ) {
collection(COL).find().toArray(function(err, docs){
res.send(docs);
})
} );

// GET find :id
router.get( '/:id', function ( req, res ) {
collection(COL).findOne( { _id: new ObjectID( req.params.id ) }, {}, function(err, r){
res.send( r );
} );
} );

// POST insert data
router.post( '/', function ( req, res ) {
collection(COL).insertOne( req.body ).then(function(r) {
res.send( r );
});
} );

// PUT update data
router.put( '/:id', function ( req, res ) {
collection(COL).findOneAndUpdate( { _id: new ObjectID( req.params.id ) }, req.body, {}, function(err, r){
res.send( r );
} );
} );

// DELETE remove data
router.delete( '/:id', function ( req, res ) {
collection(COL).findOneAndDelete( { _id: new ObjectID( req.params.id ) }, {}, function(err, r){
res.send( r );
} );
} );

module.exports = router;


3.自動生成された不要なファイルを削除。

$ rm routes/index.js; rm routes/users.js; rm views/*


確認

$ curl http://localhost:3000/api -X POST -d "name=name1"

$ curl http://localhost:3000/api -X POST -d "name=name2"
$ curl http://localhost:3000/api
$ curl http://localhost:3000/api/xxxxxxxxxxxxxxxxxxxxxxxx
$ curl http://localhost:3000/api/xxxxxxxxxxxxxxxxxxxxxxxx -X PUT -d "name=update"
$ curl http://localhost:3000/api
$ curl http://localhost:3000/api/xxxxxxxxxxxxxxxxxxxxxxxx -X DELETE
$ curl http://localhost:3000/api


これまでの内容をgitにcommit

.gitignore作成(gitignoreで作るとよい)。


# Created by https://www.gitignore.io/api/node

### Node ###
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history

gitにcommit

$ git init

$ git add .
$ git commit -m "first commit"


Herokuへデプロイ

https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction

に従う。以下、簡単な手順。

1.Herokuのアカウント作成とHeroku Toolbeltのインストール

2.Herokuにプロジェクト作成

ita-restapi部分(名前)は使われているとエラーになるので注意。

$ heroku login

$ heroku create ita-restapi

アプリのURLとGitのURLが表示される。

https://ita-restapi.herokuapp.com/ | https://git.heroku.com/ita-restapi.git

3.Procfile作成

web: DEBUG=restapi:* npm start

4.mongolabの作成

https://devcenter.heroku.com/articles/mongolab

$ heroku addons:create mongolab --app ita-restapi

$ heroku config --app ita-restapi | grep MONGOLAB_URI

mongolalのURIが表示される

MONGOLAB_URI: mongodb://heroku_xxxxxxxx:yyyyyyyyyyyyyyyyyyyyyyyyyy@zzzzzzzz.mongolab.com:37185/heroku_xxxxxxxx

5.mongo.jsのurlを変更する

Heroku用にブランチをきる。

$ git checkout -b heroku

mongo.jsを変更する。


mongo.js

(前略)

// Connection URL
//var url = 'mongodb://localhost:27017/restapi';
var url = 'mongodb://heroku_xxxxxxxx:yyyyyyyyyyyyyyyyyyyyyyyyyy@zzzzzzzz.mongolab.com:37185/heroku_xxxxxxxx';
(後略)

コミット

$ git add .

$ git commit -m "Change mongodb url for heroku"

6.Herokuにデプロイ

$ git remote add heroku https://git.heroku.com/ita-restapi.git

$ git push heroku heroku:master


完成品(master)

https://github.com/itagakishintaro/restapi