* Express(Nodejs)でWebAPI作成 [#hefe13a8] #setlinebreak(on); #contents -- 関連 --- [[Spring BootでWebAPI作成]] --- [[EC2上のExpressのパフォーマンス検証]] ** インストールからアプリケーション作成まで [#v3bc94af] #html(<div style="padding-left:10px;">) *** expressインストール(グローバル) [#s8e7d590] #html(<div style="padding-left:10px;">) #code(myterm2 nolinenums){{ npm install -g express }} #html(</div>) *** expressコマンドを使用できるようにする(グローバル) [#jba5058a] #html(<div style="padding-left:10px;">) #code(myterm2 nolinenums){{ npm install -g express-generator }} #html(</div>) *** 環境変数の設定(グローバルインストールした場合) [#zd6bb844] #html(<div style="padding-left:10px;">) #code(myterm2 nolinenums){{ export NODE_PATH=/usr/local/lib/node_modules }} #html(</div>) *** アプリケーション作成&必要なモジュールのインストール [#z1034d29] #html(<div style="padding-left:10px;">) #code(myterm2 nolinenums){{ express sample cd sample && npm install }} #html(</div>) #html(</div>) ** 起動確認 [#t1c4f213] #html(<div style="padding-left:10px;">) *** 起動確認用の sample.js 作成 [#qdba62bc] #html(<div style="padding-left:10px;">) sample.js #code(mycode2){{ var express = require('express'); var app = express(); app.get('/', function(req, res){ res.send("Hello World!!\n"); }); app.listen(3000); }} #html(</div>) *** サンプル起動 [#d8740cd5] #html(<div style="padding-left:10px;">) #code(myterm2){{ node sample.js }} #html(</div>) *** サンプル確認 [#o8a33e21] #html(<div style="padding-left:10px;">) #code(myterm2 nolinenums){{ curl -v http://localhost:3000 }} #html(</div>) #html(</div>) ここからは、実際にDBからデータを取得するAPIを作成する。 ** テスト用DBの準備(MySQL) [#c6efc2a0] #html(<div style="padding-left:10px;">) #include(テスト用DBの準備(MySQL),notitle); *** MySQLモジュールのインストール [#jf8ebb54] #html(<div style="padding-left:10px;">) package.json を編集 #code(mycode2 linenums:8){{ "dependencies": { "body-parser": "~1.18.2", "cookie-parser": "~1.4.3", "debug": "~2.6.9", "express": "~4.15.5", "jade": "~1.11.0", "morgan": "~1.9.0", "mysql": "*", // 追加 }} インストール #code(myterm2){{ npm install }} #html(</div>) *** app.js を編集 [#ac8077d7] #html(<div style="padding-left:10px;">) app.js #code(mycode2 linenums){{ var express = require('express'); . . // ## ここから追加 ## var mysql = require("mysql"); var pool = mysql.createPool({ connectionLimit : 10, host: process.env.NODE_DB_HOST || 'localhost', port: process.env.NODE_DB_PORT || '3306', user: process.env.NODE_DB_USER || 'example_user', password: process.env.NODE_DB_PASS || 'example_pass', database: process.env.NODE_DB_NAME || 'example_db' }); pool.on('connection', function (connection) { console.log("新しいコネクションプールが作成されました"); }); pool.on('acquire', function (connection) { console.log("コネクションプールから接続が獲得されました"); }); pool.on('release', function () { console.log("コネクションプールが戻されました"); }); pool.on('enqueue', function () { console.log("エンキュー"); }); global.pool = pool; // ## ここまで ## var index = require('./routes/index'); var users = require('./routes/users'); var books = require('./routes/books'); // 追加 . . app.use('/', index); app.use('/users', users); app.use('/book', books); // 追加 }} #html(</div>) *** routes/books.js を作成 [#ked0fb03] #html(<div style="padding-left:10px;">) #code(mycode2 linenums){{ var express = require('express'); var router = express.Router(); router.get('/', function(req, res, next) { var data = []; pool.query('select * from books', function(err, rows, fields) { if (err) throw err; res.json(rows); }); }); router.get('/:id', function(req, res, next) { const id = req.params.id; pool.query('select * from books where id = ?', id, function(err, rows, fields) { res.json(rows); }); }); module.exports = router; }} #html(</div>) *** トランザクションを張る場合 [#w1cdd426] #html(<div style="padding-left:10px;">) トランザクションを張る場合は以下のように明示的に beginTransaction する必要がある。 ※常にトランザクションを張る場合は、pool あたりをラップすれば、上記のコードと殆ど変わらないコード量にはできそう。 #code(mycode2){{ var express = require('express'); var router = express.Router(); router.get('/', function(req, res, next) { pool.getConnection(function(err, connection) { if (err) throw err; connection.beginTransaction(function(err) { connection.query('insert into xxxxx ... ', function(err, rows, fields) { if (err) { return connection.rollback(function() { connection.release(); throw err; }); } connection.commit(function(err) { connection.release(); }); res.json({"result":"true"}); }); }); }); }); }} #html(</div>) *** 起動 [#t9d61408] #html(<div style="padding-left:10px;">) #code(myterm2 nolinenums){{ DEBUG=sample:* npm start }} #html(</div>) #html(</div>) ** 開発メモ [#pceae8e0] #html(<div style="padding-left:10px;">) *** 変更したときにオートリロードする [#u931613a] #html(<div style="padding-left:10px;">) #code(myterm2 nolinenums){{ npm install -g node-dev cd myapp node-dev bin/www }} #html(</div>) #html(</div>)