I want to log every request with response information.
I tried to use middleware, and I have a problem.
res.body
is undefined.
app.use((req, res, next) => {
var time = Date.now();
res.on('finish', function() {
var clientIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
var method = req.method;
var path = req.baseUrl;
var duration = Date.now() - time;
console.log({
clientIp,
elapsedTime: `${duration}ms`,
hostname: req.headers.host,
level: 'INFO',
method,
path,
phase: process.env.NODE_ENV,
reqBody: req.body,
reqHeaders: req.headers,
resBody: res.body,
resHeaders: res.getHeaders(),
status: res.statusCode
});
});
next();
});
Actually there is response data on client.
How can I get response body in middleware?
You can call $response->setContent('foobar content'); to set the contents value or $response->getContent(); to receive the content value. If $response->getContent(); returns null, then you have to check the object type of $response. Maybe its not \Illuminate\Http\Response . Hope it helps.
To log the response body with Express, we can create our own middleware to intercept the response and log it. const logResponseBody = (req, res, next) => { const oldWrite = res. write const oldEnd = res. end; const chunks = []; res.
Middleware functions can perform the following tasks: Execute any code. Make changes to the request and the response objects. End the request-response cycle.
json() is a built-in middleware function in Express. This method is used to parse the incoming requests with JSON payloads and is based upon the bodyparser. This method returns the middleware that only parses JSON and only looks at the requests where the content-type header matches the type option.
The response can be intercepted by overriding response.json
function. By doing so, and adding our custom function
, every time, response.json()
is called, our intercepting function is triggered.
middleware/response.filter.js:
// Response Interceptor Middleware
export default (request, response, next) => {
try {
const oldJSON = response.json;
response.json = (data) => {
// For Async call, handle the promise and then set the data to `oldJson`
if (data && data.then != undefined) {
// Resetting json to original to avoid cyclic call.
return data.then((responseData) => {
// Custom logic/code.
response.json = oldJSON;
return oldJSON.call(response, responseData);
}).catch((error) => {
next(error);
});
} else {
// For non-async interceptor functions
// Resetting json to original to avoid cyclic call.
// Custom logic/code.
response.json = oldJSON;
return oldJSON.call(response, finalResponse);
}
}
} catch (error) {
next(error);
}
}
In the Server.js
file, register the middleware:
// Server.js file
import externalResponseFilter from "./middleware/response.filter.js:";
// Create Express server
const app = express();
// Response interceptor - Initialization.
app.use(externalResponseFilter);
And in the controller where you are returning the response
, return with response.json()
function instead of response.send()
.
Let me know if any additional explanation is required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With