Server-Side

Node JS II


  • Express JS
  • Sequelize ORM
  • Advanced JavaScript

Version


v1.2 13 November 2021
v1.1 9 November 2021
v1.0 5 November 2021

Acknowledgments


Thanks to:
  • Hamzeh Roumani, who has shaped EECS-4413 into a leading hands-on CS course at EECS and who generously shared all of his course materials and, more importantly, his teaching philosophy with me;
  • Parke Godfrey, my long-suffering Master’s supervisor and mentor; and
  • Suprakash Datta for giving me this opportunity to teach this course.

Download PDF

ExpressJS

About Express

Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It is an open source framework developed and maintained by the Node.js foundation.

ExpressJS is a web application framework that provides you with a simple API to build websites, web apps and back ends. With ExpressJS, you need not worry about low level protocols, processes, etc. Express provides a minimal interface to build our applications. It provides us the tools that are required to build our app. It is flexible as there are numerous modules available on npm, which can be directly plugged into Express. Express was developed by TJ Holowaychuk and is maintained by the Node.js foundation and numerous open source contributors.

Express Routing

Routing refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on). Each route can have one or more handler functions, which are executed when the route is matched. Route definition takes the following structure:

Where:

  • app is an instance of express.
  • METHOD is an HTTP request method, in lowercase.
  • PATH is a path on the server.
  • HANDLER is the function executed when the route is matched.

Express Static Files

To serve static files such as images, CSS files, and JavaScript files, use the express.static built-in middleware function in Express.

For example, use the following code to serve images, CSS files, and JavaScript files in a directory named public:

Now, you can load the files that are in the public directory:

To use multiple static assets directories, call the express.staticmiddleware function multiple times:

To create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function, specify a mount path for the static directory, as shown below:

Now, you can load the files that are in the public directory from the /static path prefix.

However, the path that you provide to the express.static function is relative to the directory from where you launch your node process. If you run the express app from another directory, it’s safer to use the absolute path of the directory that you want to serve:

Express Session

A website is based on the HTTP protocol. HTTP is a stateless protocol which means at the end of every request and response cycle, the client and the server forget about each other. This is where the session comes in. A session will contain some unique data about that client to allow the server to keep track of the user’s state. In session-based authentication, the user’s state is stored in the server’s memory or a database.

To initialize the session, we will set the session middleware inside the routes of the individual HTTP requests. When a client sends a request, the server will set a session ID and set the cookie equal to that session ID. The cookie is then stored in the set cookie HTTP header in the browser. Every time the browser (client) refreshes, the stored cookie will be a part of that request.

Resources:

Sequelize


Object Relational Mapping

Object Relational Mapping

Object-Relational Mapping (ORM) is a technique that lets you query and manipulate data from a database using an object-oriented paradigm. When talking about ORM, most people are referring to a library that implements the Object-Relational Mapping technique, hence the phrase “an ORM”.

An ORM library is a completely ordinary library written in your language of choice that encapsulates the code needed to manipulate the data, so you don’t use SQL anymore; you interact directly with an object in the same language you’re using.

Key Features

Some of the key features are as follows:

  • It makes the application independent of the database management system being used in the backend, and so you can write a generic query. In case of migrating to another database, it becomes fairly a good deal to have ORM implemented in the project.
  • Hassles of coders are reduced to learn SQL syntaxes separately for whichever database being used to support the application. Coders can shift their focus on optimizing the code and improving performance rather than dealing with connectivity issues.
  • All small or big changes can be carried out via ORM, so there are no such restrictions when we deal with data. For example, JDBC comes with a lot of restrictions on extracting a result-set, process it and then commit it back to the database. This is not the case with ORMs. Even a single cell in the database can be retrieved, changed and saved back.
  • The connection becomes robust, secure as there will be less intervention in code. It will handle all the necessary configurations required to map application programming language with the database’s query language since there will be lesser intervention promoting secure application as a whole.
  • There is a fairly large deal of ORMs present in the market as per the application language used. One can choose easily as per business requirements.
  • There is an attached disadvantage in using ORM as well. That is when the database is in legacy file systems and disarranged. It becomes a task to arrange a whole lot of data and then map this with ORM. It is thereby suggested to use ORM when the back end is fairly managed.

Pros and Cons

Using ORM saves a lot of time because:

  • DRY: You write your data model in only one place, and it’s easier to update, maintain, and reuse the code.
  • A lot of stuff is done automatically, from database handling to I18N.
  • It forces you to write MVC code, which, in the end, makes your code a little cleaner.
  • You don’t have to write poorly-formed SQL (most Web programmers really suck at it, because SQL is treated like a “sub” language, when in reality it’s a very powerful and complex one).
  • Sanitizing; using prepared statements or transactions are as easy as calling a method.

Using an ORM library is more flexible because:

  • It fits in your natural way of coding (it’s your language!).
  • It abstracts the DB system, so you can change it whenever you want.
  • The model is weakly bound to the rest of the application, so you can change it or use it anywhere else.
  • It lets you use OOP goodness like data inheritance without a headache.

Some of other highlights of ORM are:

  • No need to learn a database query language.
  • It propagates the idea of data abstraction, thus improving data security.
  • Instead of storing big procedures in pl/SQL in the backend, these can be saved in the frontend. It improves flexibility to make changes.
  • If there are many relations like 1: m, n: m and lesser 1:1 in database structure, then ORM works well.
  • It reduces the hassles for coders by reducing the database query part handling.
  • Queries via ORM can be written irrespective of whatever database one is using in the back end. This provides a lot of flexibility to the coder. This is one of the biggest advantages offered by ORMs.
  • These are available for any object-oriented language, so it is not only specific to one language.

But ORM can be a pain:

  • You have to learn it, and ORM libraries are not lightweight tools;
  • You have to set it up. Same problem.
  • Performance is OK for usual queries, but a SQL master will always do better with his own SQL for big projects.
  • It abstracts the DB. While it’s OK if you know what’s happening behind the scene, it’s a trap for new programmers that can write very greedy statements, like a heavy hit in a for loop.

Advanced JavaScript

JavaScript Callbacks

In JavaScript, a callback is a function passed into another function as an argument to be executed later.

Wrong Order

Fixed

Fixed

Handling Errors

Nesting Callbacks

Callback Hell

Nesting many asynchronous functions inside callbacks is known as the Pyramid of Doom or Callback Hell:

To avoid the pyramid of doom, you use promises or async/await functions.

JavaScript Closure

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

Promise API

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action’s eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.

A Promise is in one of these states:

pending
Initial state, neither fulfilled nor rejected.
fulfilled
The operation was completed successfully.
rejected
The operation failed.

A pending promise can either be fulfilled with a value or rejected with a reason (error). When either of these options happens, the associated handlers queued up by a promise’s then method are called. If the promise has already been fulfilled or rejected when a corresponding handler is attached, the handler will be called, so there is no race condition between an asynchronous operation completing and its handlers being attached.

Chained Promises

A series of chained promises

Promise Methods

Static Methods
  • Promise.all(iterable)
  • Promise.allSettled(iterable)
  • Promise.any(iterable)
  • Promise.race(iterable)
  • Promise.reject(reason)
  • Promise.resolve(value)
Instance Methods
  • catch()
  • then()
  • finally()

Sequelize: Promise-based ORM

Sequelize is a promise-based Node.js ORM tool for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server. It features solid transaction support, relations, eager and lazy loading, read replication and more.

Currying

Currying is an advanced technique of working with functions. Currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each takes a single argument. Currying is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c).

Supplant

Supplant does variable substitution on the string. It scans through the string looking for expressions enclosed in {{ }} braces. If an expression is found, use it as a key on the object, and if the key has a string value or number value, it is substituted for the bracket expression and it repeats. This is useful for automatically fixing URLs or for templating HTML.

This slide is intentionally left blank.

Return to Course Page