Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the 'req' and 'res' parameters in node and node middleware?

I'm new to Node and Express and the other layers that go along with building web apps with node and the request and response parameters are really confusing me. My confusion lies in the fact that those two parameters are often present in a function but oftentimes one or both of them isn't declared. Also, much of the time an additional parameter will be thrown in, like 'next' or something else. For example, I have the following router for an API:

router.route('/teams')
    // create a team at POST http://localhost:8080/api/teams
    .post(function(req, res) {
        var team = new Team();
        team.name = req.body.name;
        team.location = req.body.location;

        // save the new team and check for errors
        team.save(function(err) {
            if (err) {
                res.send(err);
            };
            res.json({ message: 'Team created!' });
        }); 
    })
    // GET all the teams at GET http://localhost:8080/api/teams
    .get(function(req, res) {
        Team.find(function(err, teams){
            if (err) {
                res.send(err);
            };
            res.json(teams);
        });
    });

Both .post and .get call a function with req and res as parameters, but req is never used. So how does the function know what to do with req or res if they're not defined and used or not used in completely different orders? Or if I named them something completely different?

What exactly is happening with requests and responses? Sorry for my ignorance. I've read the documentation but it's not clicking.

Thanks.

like image 950
reknirt Avatar asked Dec 14 '22 22:12

reknirt


1 Answers

When you use expressApp.use('/some/route', myRouteHandler); Express will listen for requests for that route, and when it's hit, it will call the function you provided (callback). It will give it three parameters: request and response, and next. (Actually could be four, but lets keep things simple.)

So, your callback might be defined like this:

function myRouteHandler(a, b, c) {
    // do stuff
};

or like this:

function myRouteHandler(req, res, next) {
    // stuff
}

or simply:

function myRouteHandler() {
    // stuff
}

Whatever you do, doesn't matter. When the app is started, express listens for requests.

When one of them matches the route (/some/route), express will, in its internal workings, call the function you provided, like this:

myRouteHandler(requestObject, responseObject, nextMiddleware);

So in the first case, you can access the request (like, request headers, full url, caller IP address or similar) by using req. In your second case, you'll access it by calling a. In the third case, you can use arguments[0].

By convention, people will use the form: myCallback(req, res) and know that Express will put the request object as the first param, and response as the second. The response object actually has a method end(), so you can end the request. If there is also a next() object, you can call the next middleware.

Say you have a route defined like this:

app.use('/api/users', checkAuthorizationHandler);
app.use('/api/users', makeSureTheIPisFromOurInternalNetwork);
app.use('/api/users', nowHandleTheResponse);

Each of those handlers gets a third param. If you name it, you'd usually in your function declaration call it 'next' parameter. It means, the next function in order.

Say your function checkAuthorizationHandler(req, res, next) will check for req.headers('auth') token and if it's ok, it will in the function body, call next().

Then the function makeSureTheIPisFromOurInternalNetwork(a, b, c) is called. It will check that the a.ip is a LAN ip address and call c();

Finally your function nowHandleTheResponse() will find all users, and respond with a JSON object of the users: arguments[1].json([user1, user2, user3]);

So, first param is something that express gives you, it's the request, second is response, third is a next middleware function in line. No matter what you call them, they are there.

P.S. You can also declare your middleware with four params:

function(error, req, res, next);

Express will actually check your function and if it finds that you have four params and not two or three, it will give you any errors thrown by the middleware that ran earlier in the chain. Meaning, if your checkAuthHandler says next(new Error('Not authorized'));, your next function might check for that error, and if it's present, not give results. Often however will the middleware which detects errors just res.end('some error message');

If I haven't confused you enough, just say, I've got more where this came from :)

like image 76
Zlatko Avatar answered Apr 09 '23 18:04

Zlatko