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:
- Node.js
- Express.js Framework
- 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
-
Opening cmd in the right path where
program.js
is located
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()
});
}
html
head
title = title
body
h1 = heading
div#container
- for user in users
div.user = user.email
<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');