Node.js 💁‍♀️

Understanding the Basics

Hyerang Raina Kim
3 min readAug 16, 2020

Node.js Lifecycle & Event Loop

Requests

const http = require('http');const server = http.createServer((req,res) => {
console.log(req.url, req.method, req.headers);
});
server.listen(3000);

Run the app.js and reload the page on localhost:3000,

/ GET {
host: 'localhost:3000',
connection: 'keep-alive',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
cookie: '_ga=GA1.1.761346872.1588227621; _xsrf=2|585a720d|b17b22e5a43fbbda17e66ad13ca0ddd3|1596442385; username-localhost-8888="2|1:0|10:1596709720|23:username-localhost-8888|44:YTQ0ODI2NjNlM2ZjNDIyYmJkM2JlOWMxNWRkMTkyYzU=|feb109ba9e14fcc04dce30bc3441220d63201e3ede0ed2fdc1f1b01c7b03e99e"'
}
  • req.url: /
  • req.method: GET
  • req.headers: rest

Sending Responses

Make sure to exit the process and restart it whenever you edit the code. Otherwise, it will not reflect your code changes.

console.log doesn’t hold the data when sending back, so instead:

const http = require('http');const server = http.createServer((req,res) => {
console.log(req.url, req.method, req.headers)
res.setHeader('Content-Type', 'text/html');
});
server.listen(3000);

We actually don’t have to set the content-type, the package that we learn later automatically does for us.

HTTP Headers

let the client and the server pass additional information with an HTTP request or response.

  • General headers apply to both requests and responses, but with no relation to the data transmitted in the body.
  • Request headers contain more information about the resource to be fetched, or about the client requesting the resource.
  • Response headers hold additional information about the response, like its location or about the server providing it.
  • Entity headers contain information about the body of the resource, like its content length or MIME type.

Streams & Buffers

if (url === '/message' && method == 'POST') {
const body = [];
req.on('data', (chunk) => {
body.push(chunk);
});
return req.on('end', () => {
const parsedBody = Buffer.concat(body).toString();
const message = parsedBody.split('=')[1];
fs.writeFileSync('message.txt', message);
res.statusCode = 302;
res.setHeader('Location','/');
return res.end();
});
}

Blocking & Non-Blocking Code

writeFileSync stands for the synchronous mode. It blocks the code execution until the text file is created.

✔️ Instead, use

fs.writeFile('message.txt', message, err => {
res.statusCode = 302;
res.setHeader('Location','/');
return res.end();
});

Then, it’s not blocking the operation and code execution!!

Single Thread, Event Loop & Blocking Code

Worker Pool section is totally detached from your js code.

  • The Event Loop

Now we’re breaking app.js file down by creating a new file, route.js.

route.js

const fs = require('fs');const { request } = require('http');const requestHandler = (req, res) => {
const url = req.url;
const method = req.method;
if (url === '/') {
res.write(
...<html rendering code> ... return res.end();
}
if (url === '/message' && method == 'POST') {
...<same as the code above in stream & buffer section> ... }
};
module.exports = requestHandler;

app.js

const http = require('http');\
const routes = require('./routes');
const server = http.createServer((req,res) => {
});
server.listen(3000);

The variable routes will ultimately hold whatever is exported in routes.js file, which is requestHandler.

Exported file is read-only! We cannot access to routes.js in app.js file. If you need to export many things, you could do by

routes.js

module.exports = {
handler: requestHandler,
someText: 'Some hard coded text'
};

OR

module.exports.handler = requestHandler;
module.exports.someText = 'Some hard coded text';

👉 Shortcuts

exports.handler = requestHandler;
exports.someText = 'Some hard coded text';

app.js

const server = http.createServer(routes.handler);

🖤 NOTES 🖤

Program Lifecylce & Event Loop

  • Node.js runs non-blocking JS code and uses an event-driven code (“Event Loop”) for running your logic
  • A Node program exits as soon as there is no more work to do
  • The createServer() event never finishes by default

Requests & Response

  • Avoid “double responses” : once it ends, do not send anther response!!

--

--