Server-Side

Node JS


  • Cross-cutting Themes
  • JavaScript - The Good Parts
  • Node JS

Version


v1.2 7 November 2021
v1.1 4 November 2021
v1.0 26 October 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

Cross-Cutting Themes


  • Security
  • Modularity
  • Versatility
  • Interoperability
  • Scalability
  • Telemetry

Security

Never trust the client

Always assume all input or data coming from the client might be sent maliciously, because you can’t control it. This means authentication and authorization must be checked and enforced server-side. All input must be validated. Never trust the user; there is nothing on the client side that can prevent them from entering dangerous, unexpected input. Always validate input and perform server-side checks on everything. Assume a malicious actor can tampered with the client and its implementation (not just webpages but mobile applications as well). Never provide direct access to the databases.

An API lets us control what features, capabilities and resources the clients have access to and helps us minimize the attack surface a malicious actor can exploit against our systems.

Hacker gaining unauthorized access to the database.

Confidentiality Protection against disclosure
  Encrypt: link level or end-to-end
  Authentication: Passwords, Accounts, OAuth
Integrity Protection against alteration
  SQL Injection: Always sanitize incoming parameters and use prepared queries
Availability Protection against interference
  Network based Measures: IP filtering, black and white lists, DoS, DDoS, …

Modularity + Versatility

Components should be loosely-coupled with multiple client apps sharing the same backend

  • With an API, the server and clients can evolve independently.
  • Allows our system to be platform- and technology-agnostic.
  • Multiple different client implementations can use the same API:

    • Web applications
    • Mobile apps
    • Desktop apps
    • Point-of-sales terminals
  • All apps share the same API, so data is synchronized and consistent.
  • If multiple apps are implemented in the same language, they can share the same code for accessing the API.
  • We can publish our APIs so that 3rd-parties can use them, build 3rd-party apps or extend our APIs as 3rd-party web services.

Interoperability

Components should be loosely-coupled and replaceable without breaking other components

  • With an API, the server and clients can evolve independently.
  • Allows our system to be platform- and technology-agnostic.
  • That means we can reimplement the server in any programming language we want.
  • As long as the new implementation replicates all of the existing features and API remains the same as before, the clients should not notice any difference.
  • That gives us, implementers the flexibility to choose the technology that best suits our application’s requirements as oppose to being locked into a certain technology or programming language; the democraticization of technology.

Scalability

Scalability: the property of the systems of remaining efficient where there is a significant increase in the number of users and resources.

  • Controlling the cost of physical resources
  • Controlling the performance loss
  • Preventing software resources from running out
  • Avoiding performance bottlenecks

Techniques

  • Multithreading
  • Throttling
  • Thread Pooling
  • Scale through containers (e.g. Docker, Kubernetes)
  • Scale through boxes (pods and nodes) or VMs
  • Load Balancing
  • Auto Scaling

Telemetry

  • System Logs
  • Performance Timing
  • Metrics
  • Analytics
  • Data Mining
  • Machine Learning

Failure Handling

  • If a part of the system fails, the system should still functions
  • Detecting failure:
    • Some failures can be detected: for example a checksum can detect corrupted data in a message, a server not responding
  • Masking failures: when a failure is detected it can be hidden or made less severe
    • Messages can be retransmitted or corrected, a server is restarted
  • Tolerating failure: if a browser cannot contact a server, it does not try forever; it gives up and inform the user
  • Recovery from failures: the software should be able to “roll-back” to a stable and know state
  • Redundancy: services can tolerate failures by using redundant components; most web applications run on clusters
  • Unsolved problems: denial of service

JavaScript


The Good Parts

JavaScript

During these formative years of the Web, web pages could only be static, lacking the capability for dynamic behavior after the page was loaded in the browser. In 1995, Netscape decided to add a scripting language to Netscape Navigator. They pursued two routes to achieve this: collaborating with Sun Microsystems to embed the Java programming language, while also hiring Brendan Eich to embed a scripting language in the browser.

Brendan Eich to devise a scripting language, with syntax similar to Java, but borrowed a lot of ideas from Scheme for lambda functions and Self for dynamic typing and prototypal object-oriented inheritance. Although the new language and its interpreter implementation were called LiveScript when first shipped as part of a Netscape Navigator beta in September 1995, the name was changed to JavaScript for the official release in December 1995.

Microsoft reverse-engineered Netscape Navigator’s JavaScript interpreter to create its own, called JScript. In November 1996, Netscape submitted JavaScript to Ecma International, as the starting point for a standard specification that all browser vendors could conform to. This led to the official release of the first ECMAScript language specification in June 1997.

JavaScript’s Key Ideas

  • Load and go delivery
  • Loose Typing
  • Objects as general containers
  • Prototypal inheritance
  • Lambda
  • Linkage through global variables

JavaScript and Java

JavaScript and Java are similar in some ways but fundamentally different in some others. The JavaScript language resembles Java but does not have Java’s static typing and strong type checking. JavaScript follows most Java expression syntax, naming conventions and basic control-flow constructs which was the reason why it was renamed from LiveScript to JavaScript.

JavaScript is a very free-form language compared to Java. You do not have to declare all variables, classes, and methods. You do not have to be concerned with whether methods are public, private, or protected, and you do not have to implement interfaces. Variables, parameters, and function return types are not explicitly typed.

JavaScript Java
Object-oriented. No distinction between types of objects.Inheritance is through the prototype mechanism, and properties and methods canbe added to any object dynamically. Class-based. Objects are divided into classes and instanceswith all inheritance through the class hierarchy. Classes and instances cannothave properties or methods added dynamically.
Variable data types are not declared (dynamic typing, loosely typed). Variable data types must be declared (static typing, strongly typed).
Cannot automatically write to hard disk. Can automatically write to hard disk.

JavaScript Types

Primitive Types
  • string
  • number
  • boolean
Complex Types
  • object
  • function
Empty Types
  • null
  • undefined
Built-in Objects
  • Object
  • Function
  • Array
  • Date
  • String
  • Number
  • Boolean
  • Symbol
  • RegExp
  • Error
  • Promise
  • Map
  • WeakMap
Static Objects
  • Math
  • JSON

For the full list of standard built-in objects, refer to here.

JavaScript Globals

Value Properties

These global properties return a simple value. They have no properties or methods.

  • Infinity
  • NaN
  • undefined
  • globalThis

Function properties

These global functions—functions which are called globally, rather than on an object—directly return their results to the caller.

  • eval()
  • isFinite()
  • isNaN()
  • parseFloat()
  • parseInt()
  • encodeURI()
  • encodeURIComponent()
  • decodeURI()
  • decodeURIComponent()

JavaScript - typeof

You can use the typeof operator to find the data type of a JavaScript variable.

Please Observe:
  • NaN is number.
  • An Array is object.
  • A Date is object.
  • null is object.
  • An undefined variable is undefined.
  • A variable that has not been assigned a value is also undefined.

Node JS


Server-side JavaScript

About Node.JS

Node.js is an asynchronous event-driven JavaScript runtime, designed to build scalable network applications. It is an open-source, cross-platform, back-end runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser. It enables developers to use JavaScript to write command line tools and server-side scripts. Developed in 2009 by Ryan Dahl.

Node.js is similar in design to, and influenced by, systems like Ruby’s Event Machine and Python’s Twisted. Node.js takes the event model a bit further. It presents an event loop as a runtime construct instead of as a library. In other systems, there is always a blocking call to start the event-loop.

Node JS: The System

The NodeJS architecture. The application interacts with the V8 JavaScript engine which provides the Node JS bindings that enables OS operations. The API calls are added to an event queue and executed by worker threads asynchronously. The event loop is provided by LibUV, an asynchronous I/O library.

NPM Package Manager

npm is a package manager for the JavaScript programming language maintained by npm, Inc.

npm is the default package manager for the JavaScript runtime environment Node.js. It consists of a command line client, also called npm, and an online database of public and paid-for private packages, called the npm registry. The registry is accessed via the client, and the available packages can be browsed and searched via the npm website. The package manager and the registry are managed by npm, Inc.

npm stands for Node Package Manager. It was released back in 2010, beginning a new era in web development. Until then, the project dependencies were downloaded and managed manually. npm was the magic wand that pushed the Web to the next level.

npm actually involves three things:

  • a website for managing various aspects of your npm experience
  • a registry for accessing an extensive public database of JavaScript packages
  • a command-line interface (CLI) for interacting with npm via the terminal

Yarn stands for Yet Another Resource Negotiator. The Yarn package manager is an alternative to npm, released by Facebook in October 2016. The original goal of Yarn was to deal with npm drawbacks, such as performance and security issues. Yarn was positioned as a safe, fast, and reliable JavaScript dependency management tool. But the npm team learned their lesson and rapidly filled the npm gaps by implementing the missing features.

TCP Client

TCP Server

HTTP Client

HTTP Server

Database Access in Node.JS

This slide is intentionally left blank.

Return to Course Page or Part II.