Basic Node and Express Module Does Not Explain Concepts Well

I hope the new FFC format addresses the problems I’m about to highlight here.

At the core of this module is the route:

app.METHOD(PATH, HANDLER)

This seems like it should be a simple concept, yet after completing this module, I still don’t have a good grasp of how to use it. If you want to blame the student, go ahead. Don’t bother reading the rest of this. If you actually care to understand what went wrong, then keep reading.

From what I can understand, the user is doing something on the ‘front-end’ and information gets passed to the ‘back-end’. The ‘route’ handles the interface between front and back end.

Here are the definitions given for each component of the route.

Route – No definition given. It’s simply asserted that this is a thing in Express, and then the lesson dives straight into its component parts. I guess we can infer what a route is based on the context. Still, a simple definition/explanation of this concept at the very beginning would be helpful.

App -> Is this just the name of the class of methods that will be called? Like Math is the class for .round(), .random() etc?

METHOD - “is an http method in lowercase” --> Adding “HTTP” to METHOD tells me nothing about the sorts of methods we’ll be calling here. The only concrete information given is that it needs to be typed in lowercase.

PATH - “is a relative path on the server” --> Adding ‘relative’ to ‘path’ does not elucidate the meaning of ‘path’ in this context. Is ‘path’ a series of folders we have to click through to find a file on the server? Based on the challenges in the module, I have no clue.

HANDLER - “is a function that Express calls when the route is matched. Handlers take the form function(req,res) {…}”` --> When is a route ‘matched’? Do you mean when a PATH is matched? How does the route know this?

“req is the request object, and res is the response object.” - Always tie in what we have learnt in prior modules to the current lesson at hand. If we’ve made it to this module, then we’ve done the front-end modules. So when we see function(req, res){...}, this looks like some generic function that takes in two arguments. So what’s passing in these arguments? I guess it’s app.METHOD. Where does app.METHOD get the ‘req’ object from? From the front-end? Well how does this object get generated on the front-end?

The node and express module fails at explaining the broad concept right at the outset. We’re then told to use app.get, app.use, app.post etc. What are these methods doing? The challenges fail at illustrating the behavior of these ‘HTTP’ methods. These are the explanations given for each HTTP method:

POST (sometimes PUT) - “Create a new resource using the information sent with the request”

GET - “Read an existing resource without modifying it”

PUT or PATCH (sometimes POST) - “Update a resource using the data sent”

DELETE => “Delete a resource.”

USE - “mount middleware”

These definitions are great and all, except I’m not sure how the challenges illustrate how they work. Take the solution to the second challenge, for example:


app.get("/", function(req, res) {

res.send('Hello Express');

});

What is ‘GET’ doing here? How does this demonstrate ‘read an existing resource without modifying it’? What happens if I use POST or USE? It seems like res.send is doing the work here, so what’s GET doing? Tell me exactly how the behavior of the route changes depending on the METHOD used. If I don’t understand how the METHOD affects the HANDLER, then I won’t know what method to use.

What happens if I put something else into the PATH? What does it mean if the PATH is “/” or “/library” or “/now” or “/:word/echo”? What happens if I type “/poopoo/peepee/lala”? How do I make that PATH mean something to the route? Where are the words after the “/” coming from? How do these words get put together on the front end? You cannot teach Node Express in isolation from whatever’s happening on the front end. SHOW us with an actual HTML document what is happening on the front end that’s sending these strings or objects to the backend.

In the last challenge #12, we have an actual HTML form that we can play with. I can see that the PATH “/name” corresponds to the ACTION in <form action = “/name”></form>. If I change ACTION to “/heck” then I need to also change PATH to “/heck” or the route wouldn’t work. Great. This nicely ties in what we learnt all the way back in the HTML/CSS module to Node-Express. If only we had this working example for most the other challenges.

At the end of the module, I only have a vague idea of how information gets sent back to the front end. Because from what I can see, if you send a json object back to the front, the entire page disappears and gets replaced by the content of the json. Well how do I take that information and use it to do something on the front end without causing the entire page to disappear? You can look at my glitch as an example of what I’m talking about:

https://boulder-helmet.glitch.me/

I would start by reading this:

And then this:

What Express exists to do is to provide the server-side of the above.

I’ll try to cover some of the things you talk about

App -> Is this just the name of the class of methods that will be called? Like Math is the class for .round(), .random() etc?

Well not really, you could call it anything you like because what it is is just the main object exported by Express:

const express = require("express");
const app = express();

Could be

const myFantasticServer = express();

It’s initialising an object with some functions attached. app is just conventionally the name you give it.

PATH - “is a relative path on the server”

A path is a string, for example: /forum/t/basic-node-and-express-module-does-not-explain-concepts-well/300009. It’s the path that the client hits to get somewhere: if I go to https://www.freecodecamp.org and attach that path, I will get this forum post back in the browser.

If you are writing app.get("/test", ....., you are literally defining a path a user can use in a browser to get something. It doesn’t represent anything in a folder structure or anything like that, you’re just saying if the user goes to https://whatever_my_site_is_called.com/test, do something. And the callback function is going to define what you do (it could say respond with some html, it could say respond with an image stored on the server, it could say just respond with a bit of plain text).

METHOD - “is an http method in lowercase” --> Adding “HTTP” to METHOD tells me nothing about the sorts of methods we’ll be calling here. The only concrete information given is that it needs to be typed in lowercase.

Express is a web server, so it is a program that takes some network http request, and responds to it. There are a specific set of http methods.

A client (eg a browser) sends some text in a specific format which includes what method is being used (GET, POST, PUT, PATCH, HEAD, etc). The server checks that, and responds with another piece of text. The client checks that and maybe sends another request, server responds and so on, back and forth, request, response, request, response.

A web server framework like Express abstracts away the bit where you manually have to check that text, and it does it by turning it into a function. So this is from the Wikipedia page on HTTP:

The request:

GET / HTTP/1.1
Host: www.example.com

The server response:

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close

<html>
  <head>
    <title>An Example Page</title>
  </head>
  <body>
    <p>Hello World, this is a very simple HTML document.</p>
  </body>
</html>

Basically in Express:

app.get("/", (req, res) => {
  res.send(`
<html>
  <head>
    <title>An Example Page</title>
  </head>
  <body>
    <p>Hello World, this is a very simple HTML document.</p>
  </body>
</html>
`);
});

When Express gets started up, it listens for requests being made. Assuming the URL of the server is http://example.com, that is saying “when there is a GET request to the root path (/) of the server (http://example.com/), run this function which specifies what the server sends back to the client that made the request.” It will create two objects, a Request object and a Response object. The Request object parses this:

GET / HTTP/1.1
Host: www.example.com

And the Response object is going to build this:

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close

<html>
  <head>
    <title>An Example Page</title>
  </head>
  <body>
    <p>Hello World, this is a very simple HTML document.</p>
  </body>
</html>

The callback function that takes two arguments ((req, res) => /* do stuff*/), those two arguments are those two objects, and res.send is one of the functions available on the Response object that lets you build out that response that is going to get sent back.

I can only really briefly cover bits of this, but I would say go through the tutorial stuff on the Express site as well (Getting Started, and then Guides):

https://expressjs.com/

4 Likes

I generally agree with all your statements that it is hard to understand what is meant by certain terms. I struggled with it also at this part. But at this part google will be your best friend. You are more on your own in terms of learning. I just pushed forward and eventually things started to make more sense. But I do still feel like I need to learn more. Study the boiler plate code from here on out to try to understand it, that will also help in completing the challenges that are coming up.

1 Like

Thank you, Dan, for taking the time to explain in greater detail how Express works, and thank you also for the links. I will go through those materials to better understand this section.

Your explanation has clarified a lot of the misconceptions I had. PATH has nothing to do with what’s on the server side. It is where the client is on the webpage - the ‘path’ the user takes to get from the main webpage to where the user currently is. So “/library” could mean they were on the main website (http://example.com/), then they clicked a button to get to the ‘library’ section of the webpage (http://example.com/library). This sends a ‘GET’ request. The server detects this and serves up the ‘library’ section of the webpage.

So, POST, GET, USE… these are all coming from the client as they interact with the website. GET is served up whenever they enter a new part of the site. POST is when they fill out a form and hit submit, etc. I see now. Hmm… We’ve encountered “POST” in the forms challenges in the html section, I believe. I’m not sure we’ve ever specified “GET” in our HTML code. Is that where “GET”, “POST”, “USE” etc come from? The HTML document?

And when Express sees these requests, and the path matches, it calls upon the HANDLER.

If I’m still understanding this wrong, please let me know. Otherwise, thank you again. It’s very generous of you to take the time to respond.

Yes, you understood correctly.

We don’t specify GET request because they are the default requests.
And as for the form, consider this example:
<form action="/login">......</form>

Here, if we don’t specify the method attribute on the form, the request will be sent to the server as GET and you will listen to any such requests with app.get('/login', ...)

And adding a POST to form like this: <form action="/login" method="POST">......</form> will make you able to listen to requests like this: app.post('/login', ...)

So in /login case (Or any form, generally speaking), typically, the GET request serves the form and the POST request handles and processes the form data.

When the user goes to /login, on the server side, something like this happens:

// If we get a `GET` request on '/login' path, we will send the login page.
app.get('/login', function(req, res) {
res.send(`
<html>
  <head>
    <title>Login Page</title>
  </head>
  <body>
    <form action="/login" method="POST">
      <input name="email" type="email" />
      <input name="password" type="password" />
    </form>
  </body>
</html>
`)
})
// If we get a `POST` request on '/login' path,
// we will see if the user exists allow them or give them some errors.
app.post('/login', function(req, res) {
   const email = req.body.email // email that user entered.
   const password = req.body.password // email that user entered.
  /* A side note: req.body contains the data that is sent 
     to us in the HTML body. And the name of the field is determined
     by the `name` attribute in our form.
     if our form had the email input like this:
    <input name="awesomeEmail" type="email" />
    then we would extract the email like this:
    const email = req.body.awesomeEmail
  */
  // Now that we have email and password,
  // We can check if the user exists in our database and give
  // appropriate response (I am not going to show you that here...)
})

And as for the other request types, like PATCH, PUT, DELETE etc, they must be sent via Javascript or from any other server, because HTML does not support these methods.
So this is invalid: <form action="/login" method="PUT" />...</form> and your sever will end up getting a default GET request on this route app.get('/login', ...)

You can google more something like this: Using PUT method in HTML forms etc and you will find a bunch of resources regarding the workarounds and why it is not supported. (The reason why these methods not supported in HTML is not very clear though)

2 Likes

So GET is normally the default, which is why you might not have seen it explicitly specified – most of the time you want to, say, GET an article or a blog post or whatever. It’s the easiest to understand in many ways as well – you type https://google.com/ for example, which says "GET https://google.com/, and the Google servers respond by sending the HTML for the Google search page.

POST is like posting a letter: you say you are making a POST request, and attach something (the body of the request). And on your Express server, this is a good example of where you’d make use of the Request object (req in the callback): that’s going to contain the details of that POST request, and you can grab the body, do something with it (then use res to send a response back to the client), like in @husseyexplores’ example.

Yep, and what you also get into here is how APIs are designed. It could literally reflect a folder/file structure on the computer the server lives on if you wanted, but that isn’t normally the case (what is a folder? What is a file?). It could sorta reflect a database structure – this is quite common (request made to get “/user/123” -> handler goes to the User table in the database and gets user with id 123 -> responds with that info to the client).

Basically, you have a program that does something: eg access/update a database, show today’s weather, do sums, show news articles, anything. What Express (or any web server) does is allow you to expose an HTTP interface for that program so that it’s accessible to the outside world: a client sends a message, formatted in one of the specific ways HTTP allows. Express understands those messages. Within that get/post/put/etc handler function, you can call your program, which does something, and then easily define what the response should be. And Express converts that back into a standard HTTP response message to send back to the client.

One other thing, re app.SOME_FUNCTION. When you do app = express(), that’s initialising an object with a load of useful functions. Some of those cover the HTTP methods (get is an abstraction over GET, post over POST, etc), some are just functions useful to the Express app (use is a function used for middleware, which gets covered a bit later) – see:

https://expressjs.com/en/4x/api.html#app

EDIT: re HTML, and why you can’t use anything except GET and POST, this is good: https://softwareengineering.stackexchange.com/a/211790 (tl/dr nobody took the time to write a specification). With an Express app, if you’re using it to serve the HTML as well via templating, it has some abstractions in place to let you get around that. But you can only GET or POST from plain HTML (controlling the server means you can imlement very simple workarounds though), otherwise you use JS to send the requests.

2 Likes

Thank you, Hussey, for providing a concrete example of how HTML relates to node/Express. This makes everything so much clearer. Now I know how to choose an HTTP method and PATH name depending on how I prepare my HTML document.

1 Like

Ah, GET is the default, so it’s not specified. That’s good to know. And thank you for explaining the app = express() at the top. Understanding why I’m typing out a line of code makes it so much easier to remember what I need to put in the code. And now that I know app could be any name, I won’t be confused if I see that the name has changed in a different example.

2 Likes