morgan-body

剛好也有人也跟我一樣有 request 和 response 的需求
使用方法很簡單,而且他還有特別處理 json 訊息格式化
基底也是使用 morgan 這個 middleware log

快速使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const express = require('express');
const morganBody = require('morgan-body');
const uuid = require('node-uuid')

const app = express();
app.use(express.json()); // 取代 bodyParser.json()

// 定義 :id token, 因為他裡面有特別用來區分哪個 req, res 是屬於哪個 :id
// 當 request 流量大時才可以找得到正確對應的 request, response log
app.use(function (req, res, next) {
  req.id = uuid.v4()
  next()
});

// 自訂錯誤訊息: morgan-Body
morganBody(app);

輸出結果

雖然用別人的也不錯
但工程師的性格還是希望可以用現有工具
做出跟他差不多的功能
把這個功能實作過程搞懂才覺得滿足哈

工程師研究的 response 攔截版本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 攔截 response body 並暫存到 res.__body_response
app.use(function (req, res, next) {
  var originalSend = res.send;
  res.send = function (body) { // res.send() 和 res.json() 都會攔截到
    res.__body_response = body;
    originalSend.call(this, body);
  }
  next();
});

// 自訂錯誤訊息
app.use(morgan(function (tokens, req, res) {
  return [
    tokens.method(req, res),
    tokens.url(req, res),
    tokens.status(req, res),
    '-',
    tokens['response-time'](req, res),
    'ms',
    '\nrequest: ' + JSON.stringify(req.body),
    '\nresponse: ' + res.__body_response, // 利用剛剛暫存的 __body_response
  ].join(' ')
}));

輸出結果

自己 DIY 版本沒有 req.id 的問題
不過建議還是要加入才會比較好追蹤 request/response LOG
加入方法參考 : use custom token formats

Summary

擷取 response 訊息的目的
基本上是用來驗證 API 回傳是否正確
其實本篇還可以再修改一下
改成只遇到 4xx 和 5xx 時才會自錄 API Log (req/res)
除非有特殊需求,不然全部記錄可是很吃空間

另外也學到 call 的用法
原來攔截 response 是需要靠覆寫/串接原先 res.send 的方法
攔截後存在 res 自己的物件裡面供後面的方法取用
其實說不定還有其他更不錯存取 response 的方式
有的話歡迎在下方↓↓↓留言推薦給我喔 !

Reference