【node.js】expressでapiサーバーを実装するときに最低限必要そうなことをまとめておく
はじめに
socket.ioを使って簡単なチャットサーバーを作ろうとしました
当初、socket.ioを使わないapiの実装はphpで、socket.ioの部分だけnode.jsで・・・と考えていたのですが
どうせならapiの部分もnode.jsで作った方がいいのかなと思ってちょっと調べことをメモ
ほしい機能
・getまたはpostリクエストを受け取ってjsonを返す
・mysqlを使う
・アクセスログ、エラーログ、アプリのログを出力
・定数をどこかにまとめる
・サーバーが落ちた時に再起動するようにしたい
使った方が便利そうなもの
・バリデーションのライブラリ
・Promiseを使ってコールバック地獄にならないように
とりあえずはこんなところだろうか
getまたはpostリクエストを受け取る
ここで必要そうなことはアクセスされるurlによって処理を振り分けることとgetとpostのパラメータを受け取ること
urlによって処理を振り分ける
app.js
var app = require("express")(); var http = require("http").Server(app); // loginにgetでアクセスされた時の処理 app.get("/login", function(req, res) { }); // registerにpostでアクセスされた時の処理 app.post("/register", function(req, res) { }); http.listen(3000, function() { console.log("listening on *:3000"); });
getパラメータとpostパラメータを受け取る
getパラメータ
app.get("/login", function(req, res) { // req.query.email // req.query.password });
postパラメータ
// postを使うにはコレが必要 var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.post("/register", function(req, res) { // req.body.email // req.body.password });
jsonを返す
これは簡単で以下
app.get("/login", function(req, res) { if (req.query.email && req.query.password) { // ログインのチェックなど if (okの場合) { req.json({ "status" => "ok" }); } else { req.json({ "status" => "ng", "message" => "emailまたはパスワードが正しくありません" }); } } else { req.json({ "status" => "ng", "message" => "emailまたはパスワードが入力されていません" }); } });
mysqlを使う
mongodbを使うことが多いようだけど今回は慣れてるmysqlを使う
【node.js】expressにてmysqlを使う方法メモ - とりあえずphpとか
が、ちょっと長くなったのでこっちにまとめた
アクセスログ、エラーログ、アプリのログ出力
実際に運用していくとなったらログ処理は必須と思う
expressの標準でmorganというのがあるようだけど、調べているとlog4jsというのを使ってる人が多そうだったので今回はこれを使う。
log.js(ログ出力用のモジュール)
var log4js = require('log4js'); // 設定 log4js.configure({ "appenders": [{ "category": "access", "type": "dateFile", "filename": "/var/www/html/example.com/log/access.log", "pattern": "-yyyy-MM-dd" }, { "category": "app", "type": "dateFile", "filename": "/var/www/html/example.com/log/system.log", "pattern": "-yyyy-MM-dd" }, { "category": "error", "type": "dateFile", "filename": "/var/www/html/example.com/log/error.log", "pattern": "-yyyy-MM-dd" }, { "type": "console" }], }); var logApp = log4js.getLogger("app"); var logAccess = log4js.getLogger("access"); var logError = log4js.getLogger("error"); // アクセスログ exports.access = log4js.connectLogger(log4js.getLogger("access"), { level: log4js.levels.INFO }); // エラーログ exports.app = function(message) { logApp.info(message); }; // アプリごとのログ exports.error = function(message) { logError.info(message); };
app.js(実際にログ出力)
var log = require('./log.js'); // アクセスログを使う設定 app.use(log.access); // アプリのログ出力 app.get("/login", function(req, res) { log.app(req.query); }); // エラーログ出力 app.use(function(err, req, res, next) { log.error(err); });
出力例
[2016-06-20 11:36:59.837] [INFO] access - ::ffff:123.456.789.012 - - "POST /register HTTP/1.1" 200 63 "" "curl/7.43.0" # アクセスログ [2016-06-20 11:38:12.485] [INFO] app - MySQLへ接続成功 # アプリのログ
定数をまとめる
node-configというのを使った
config/default.json(設定ファイル)
{ "db": { "host": "db_host", "user": "db_user", "password": "db_password", "database": "db_name" }, "log": { "appenders": [{ // ログのところに書いた内容とか }], } }
mysqlへの接続情報やlogの出力設定などはここにまとめておくと良いと思う
app.js(設定を呼び出す)
var config = require("config"); // config.dbで呼び出し
サーバーが落ちた時に再起動したい
pm2というのを使ってみた。app.jsが落ちても再起動してくれる。
まだわからないけど、現時点ではこれでいこうかなと思ってます
使ってみたコマンドは以下
# サーバー起動 # --watchつけるとjsを編集すると自動で再起動してくれるので開発中はあった方が楽かと思う ./node_modules/pm2/bin/pm2 start app.js --watch # コンソールに出力されるログの監視 ./node_modules/pm2/bin/pm2 logs # サーバーの動作状況確認 ./node_modules/pm2/bin/pm2 list ┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │ ├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤ │ app │ 0 │ fork │ 23996 │ online │ 5 │ 19m │ 43.254 MB │ enabled │ └──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘ # サーバー停止 ./node_modules/pm2/bin/pm2 stop 0 # 0は上のidの数字 ./node_modules/pm2/bin/pm2 delete all # 全て停止する場合
バリデーション
node-validatorというのがあった。便利そう
var validator = require('validator'); app.post("/register", function(req, res) { if (!validator.isEmail(req.body.email)) { // チェックエラー } });
Promiseを使ってコールバック地獄にならないように
今度できたらメモする
ただ、コールバックが3つとかなり始めると見るのも嫌になりそうなので使った方が良さそう
さいごに
とりあえず実際にいじってみて上記なようなものがあれば、最低限いける気がしました
ただ、実際に仕事で使ってないので実際やってみたら全然たりなかったり問題点が見つかるのだろうな・・・
以上です