Node Express Req and Res Objects

Node Express Req and Res Objects
0

Everything I have read so far explains that anonymous functions are created as so:

function (arg1, arg2) {
return arg1+arg2
}

And from the above arg1 and arg2 and can be any datatype depending on how I call it. This is all good and I understand that but this doesn’t seem to apply to certain Express functions or there is something I am not understanding correctly. On my first Express lesson here https://www.freecodecamp.org/learn/apis-and-microservices/basic-node-and-express/start-a-working-express-server you use a callback function as so:

function(req, res) {
  res.send('Response String');
}

This Express function looks identical to the function (syntax wise) I listed above but somehow it creates the res and req become objects (or they are reserved objects/words) because they have properties and methods like res.send.

The documentation for the Express app.METHOD says that it should be used as so:

app.METHOD(path, callback [, callback …])

so after “path” you specify a callback function. My understanding is that you create this function. They then give an example:

app.get('/user/:id', function (req, res) {
  res.send('user ' + req.params.id)
})

here are my questions:
If we refer back to the very top of the post about my understanding of how functions work then it would imply that the ‘req’ argument somehow needs to be assigned a value when it is called. I am assuming that in this example the value is ‘/user/:id’ but how does it receive it? And how does this get passed through?
Also even if that was the case then the value of this ‘req’ varible/object would just be ‘/user/:id’ of the string datatype; but in the doco it clearly states that req and res are both objects with a bunch of properties. How does that work? Are these req and res objects somehow reserved words/variable/objects?

To show how all this conflicts, if we were to use the same app.get but replace their example callback function with mine above we would get:

app.get('/user/:id', function (arg1, arg2) {
console.log (arg1);
  res.send('user ' + req.params.id)
})

In this last example it would log ‘/user/:id’ to the console. And as I understand it, it should just be a string so how is that then when arg1 and arg2 change to req and res do they somehow automatically become precanned objects with certain properties?

Hey @graham,

you can call function parameters whatever you like, so this is identical to your example:

 app.get('/user/:id', function (request, response) {
  response.send('user ' + request.params.id)
});

app.get() works almost the same way as HTMLElement.addEventListener(eventType, callback); if you ever used it on the front. Your express app just listens for a request to provided path and fires callback you’ve provided passing it Request and Response objects - this is basis of async programming. Request and Responses objects are property of Express router, you never specify them.

Regarding logging Request object as string, I’m hugely sceptical about this. In normal flow it would log Request object in your example.

Hi Snigo,
I know about naming params whatever you want. My questions around the req and res objects. Am I right in saying then that the app.get method returns two values which then get passed onto your function? And these two values, the first being the req object and the second being the res object? This would now make sense as to how your function can then do something with these two objects passed through. I think this is the bit I wasn’t getting.

app.get() method doesn’t return anything, that’s why you never assign it. It works something like this:

const app = {
  GET_ROUTES: new Map(),
  get(path, callback) {
    this.GET_ROUTES.set(path, callback);
  },
};
// pseudo NodeJS http event:
http.on('incomingRequest', (req) => {
  const method = req.method;
  const path = req.path;
  const res = new Response();
  if (method === 'GET') {
    if (app.GET_ROUTES.has(path)) {
      const callback = app.GET_ROUTES.get(path);
      // Here Express would execute your callback
      callback(req, res);
    }
  }
});

Of course this is very simplified example, but generally, this is what happens: when you run get method, Express would save path and callback you provided in some Map and later when http server (of NodeJS) will receive incoming message, it will parse it and create Request object. Express then will take this object and check if it has that route in the Map and if yes it will create Response instance and execute your callback, passing Request and Response objects.

I think I’ve figured it out myself. Maybe I’m not asking the right questions as I don’t understand it properly but here is the solution to what I was trying to figure out.

I saw another example of nodejs using the fs library as so:

var fs = require( "fs" );
fs.readFile( 'inputfile1.txt' , function (ferr, filedata) {

if (ferr) return console.error(ferr);

console.log(filedata.toString());
});
console.log( "End of Program execution" `);

So my question here is similar to before. Where is my callback function getting the ‘ferr’ and ‘filedata’ objects from? They are obviously being passed in from the fs.readfile method. I went to lookup this method to see exactly what is passed to your callback function and if there are any other objects passed in. If I look it up here https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback it lists them; so now I can see where the callback function gets those objects from and I now understand.

However, the Express documentation doesn’t show this for the app.get or app.METHOD. If you look the Express doco I can’t find anywhere where it shows what objects are passed onto a callback function. This is now obvious but at least IMO it should be listed in the documentation and clear for transparency. What do I mean by this? Maybe I am using the wrong terminology when I say “output” but what I mean is that the article which describes the app.METHOD should state that it outputs the two objects req and res in that order so you know to build your function around this.

No. You are passing a function. Whenever NodeJS will finish reading the file, it will invoke your call back passing data it just read, like so callback(null, data). If, however, there’s some error, like restricted file permission, it will invoke same callback like so callback(error_message).

Here’s analogy for you to better understand principle of async programming:
I call you on a phone and give you a challenge: “Multiply 3854 times 34 in head”

This will take some time, right? Same here, reading file or waiting until someone will hit the endpoint will take time.

Now, I cannot afford to sit and wait until you come up with the answer as I have only one line and this is blocking my operation. So I putting you on hold and giving you callback option “Press * when you’re ready”. Meanwhile I’ll do other stuff.

When you’ve got the answer you’re pressing “*” on the phone and telling me the answer - this is equivalent of invoking callback like this:

pressStar(answer);

pressStar function is something that I gave you to be able to connect with me later and communicate answer back to me. The same way you’re providing Express or Node with option to connect with you in future. As I mentioned this is a backbone of async programming.

No. You are passing a function.

So whereas I am saying the method is passing those objects to the function, you are saying it’s the other way around, we are passing the function to the app.get method?