Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get response body in middleware?

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?

like image 299
kkangil Avatar asked Aug 19 '19 06:08

kkangil


People also ask

How do I get response to 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.

How do you log a body response?

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.

Can middleware be used in response?

Middleware functions can perform the following tasks: Execute any code. Make changes to the request and the response objects. End the request-response cycle.

What does the Express json () middleware do?

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.


1 Answers

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.

like image 57
Sagar Chilukuri Avatar answered Sep 21 '22 15:09

Sagar Chilukuri