Node.js

https://joecreager.com/learnyounode-unofficial-companion/

https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs

Backend

Technologies used for Backend in this course:

  1. Node.js
  1. Express.js Framework
  1. Node Package Manager NPM (Dependency Management)

Node.js

JavaScript runtime environment = executes JavaScript code outside a web browser but in Chrome's V8 Engine.

Used to make Web Servers and networking tools.

"JavaScript everywhere" paradigm:

web-application development around a single programming language, rather than different languages for server-side and client-side scripts.

Example: Simple Node.js Webserver Example (without Express)

const	http = require('http'); //importing package
const	requestListener	=	function (req,	res)	{
res.writeHead(200);	//200 in header -> OK
res.end('Hello,	World!');
}
const	server =	http.createServer(requestListener);
server.listen(8080); //listening on Port 8080

Here:

req stands for HTTP request

res stands for HTTP response

Executing a Node.js program

  1. Opening cmd in the right path where program.js is located
  1. node program.js

Express

Routes / URL Mapping

const	express	=	require('express');
const	app	=	express();app.get('/hello',	function(req,	res)	{
res.send('Hello	World!');
});const	port	=	3000;
app.listen(port,	function()	{
console.log(`Waiting	for	requests	on	Port ${port}!`);
});

Here in app.get() :

  • Request Method = GET
  • path = '/hello'
  • response = res.send()

Request and Response Objects

Here we search for a recipe via its ID to update it:

app.put('/recipes/:id', (req, res) => { //:id as a variable
const recipeId = req.params.id;
const hasImage = req.query.hasImage == 'true'; //?hasImageconst recipe = Recipes.find(recipeId, hasImage);
if(!recipe) {
return res.sendStatus(404); //not found
}
const payload = req.body; //payload is received body
recipe.update(payload);
res.send({updateSuccess : recipeId}); //JSON
});

Middleware

Processing data from client with "Middleware functions":

// for parsing application/json
app.use(express.json());
// for parsing HTML form data
// application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
...
const payload = req.body;
...

Also have access to .next()

Cookies and Sessions

Cookies can be set by both client and server as part of HTTP headers and are transmitted with every request/response cycle.

Sessions use cookies to store a unique identifier.

The associated session data is stored on the server.

routes.get('/', async (req, res) => {
let sessionId = req.cookies.sessionId; //parsed by middleware
...
if(!sessionId) {
...
res.cookie('sessionId', sessionId); //Cookie written into response header
}
...
}

Environment Variables / Configuration (secrets)

Configuration can be kept a secret.

const	db	=	require('db')
db.connect({
host:	process.env.DB_HOST,
username:	process.env.DB_USER,
password:	process.env.DB_PASS
})

Other ways to pass configuration to the program (pass parameters, read from configuration file, etc.)

const	port	=	process.argv.length	>=	3	?	+process.argv[2] : 3000;

Templating (Templates / Views)

Separation between program logic and output.

app.set('view	engine', 'pug'); //enabled by middleware
...
routes.get('/',	async	(req,	res)	=>	{
res.render('users',	{
title: 'Users',
heading: 'List of users',
users: getUsers()
});
}

\downarrow

html
head
title = title
body
h1 = heading
div#container
-	for	user in users
div.user = user.email

\downarrow

<html>
<head>
<title>Users</title>
</head>
<h1>List of users</h1><div id="container">
<div class="user">
jane.doe@tuwien.ac.at
</div>
<div class="user">
jack.bauer@tuwien.ac.at
</div>
</div>
</html>

Networking

Many Libraries, ie. node-fetch to fetch resources from other APIs

const	fetch	=	require('node-fetch'); //import
...
const	response = await fetch(objectRequestUrl(objectID));
if(response.status !== 200) { //not successful
console.log('Could not find object with id'	+	objectID);
return	false;
}
const	object = await response.json();

Persistent Storage (Files)

Filesystem utilities have synchronous and asynchronous API in Node

const	fs = require('fs');
const	path = require('path');
const	destinations = JSON.parse(fs.readFileSync(path.join(__dirname,	'../res/data.json'))); 

Modules

≠ ES6 Modules like in JavaScript but similar

const search = async (term, max=100) => { ... }
...
module.exports.search = search;
const met = require('../utils/met.js');
const artworks = met.search('van gogh');