JavaScript is at the fingertips of every frontend web developer, making it a very popular programming language, so much so that it is stereotyped as being for client-side code in web pages. The chances are that, having picked up this book, you've heard of Node.js, a programming platform for coding in JavaScript outside web browsers. Now about ten years old, Node.js is becoming a mature programming platform that's widely used in projects both big and small.
This book will give you an introduction to Node.js. By the end of this book, you will have learned about the complete lifecycle of developing server-side web applications using Node.js, from concept to deployment and security. In writing this book, we have presumed the following:
- You already know how to write software.
- You are familiar with JavaScript.
- You know something about developing web applications in other languages.
When we evaluate a new programming tool, do we latch on because it's the popular new tool? Maybe some of us do that, but the mature approach is to weigh one tool against another. That's what this chapter is about, presenting the technical rationale for using Node.js. Before getting to the code, we must consider what Node.js is and how it fits in the overall marketplace of software development tools. Then we will dive right into developing working applications and recognize that often the best way to learn is by rummaging around in working code.
We will cover the following topics in this chapter:
- An introduction to Node.js
- What you can do with Node.js
- Why you should use Node.js
- The architecture of Node.js
- Performance, utilization, and scalability with Node.js
- Node.js, microservice architecture, and testing
- Implementing the twelve-factor app model with Node.js
Overview of Node.js
Node.js is an exciting new platform for developing web applications, application servers, any sort of network server or client, and general-purpose programming. It is designed for extreme scalability in networked applications through an ingenious combination of server-side JavaScript, asynchronous I/O, and asynchronous programming.
While only ten years old, Node.js has quickly grown in prominence and is now playing a significant role. Companies, both large and small, are using it for large-scale and small-scale projects. PayPal, for example, has converted many services from Java to Node.js.
The Node.js architecture departs from a typical choice made by other application platforms. Where threads are widely used to scale an application to fill the CPU, Node.js eschews threads because of their inherent complexity. It's claimed that with single-thread event-driven architectures, the memory footprint is low, throughput is high, the latency profile under load is better, and the programming model is simpler. The Node.js platform is in a phase of rapid growth, and many see it as a compelling alternative to the traditional web application architectures using Java, PHP, Python, or Ruby on Rails.
At its heart, it is a standalone JavaScript engine with extensions that is suitable for general-purpose programming and that has a clear focus on application server development. Even though we're comparing Node.js to application-server platforms, it is not an application server. Instead, Node.js is a programming runtime akin to Python, Go, or Java SE. While there are web application frameworks and application servers written in Node.js, it is simply a system to execute JavaScript programs.
The key architectural choice is that Node.js is event-driven, rather than multithreaded. The Node.js architecture rests on dispatching blocking operations to a single-threaded event loop, with results arriving back to the caller as an event that invokes an event handler function. In most cases, the event is converted into a promise that is handled by an async function. Because Node.js is based on Chrome's V8 JavaScript engine, the performance and feature improvements implemented in Chrome quickly flow through to the Node.js platform.
The Node.js core modules are general enough to implement any sort of server that is executing any TCP or UDP protocol, whether it's a Domain Name System (DNS), HTTP, internet relay chat (IRC), or FTP. While it supports the development of internet servers or clients, its biggest use case is regular website development, in place of technology such as an Apache/PHP or Rails stack, or to complement existing websitesāfor example, adding real-time chat or monitoring existing websites can easily be done with the Socket.IO library for Node.js. Its lightweight, high-performance nature often sees Node.js used as a glue service.
A particularly intriguing combination is the deployment of small services on modern cloud infrastructure using tools such as Docker and Kubernetes, or function-as-a-service platforms, such as AWS Lambda. Node.js works well when dividing a large application into easily deployable microservices at scale.
With a high-level understanding of Node.js under our belt, let's dig a little deeper.
The capabilities of Node.js
Node.js is a platform for writing JavaScript applications outside web browsers. This is not the JavaScript environment we are familiar with in web browsers! While Node.js executes the same JavaScript language that we use in browsers, it doesn't have some of the features associated with the browser. For example, there is no HTML DOM built into Node.js.
Beyond its native ability to execute JavaScript, the built-in modules provide capabilities of the following sort:
- Command-line tools (in shell script style)
- An interactive-terminal style of programāthat is, a read-eval-print loop (REPL)
- Excellent process control functions to oversee child processes
- A buffer object to deal with binary data
- TCP or UDP sockets with comprehensive, event-driven callbacks
- DNS lookup
- An HTTP, HTTPS, and HTTP/2-client server layered on top of the TCP library filesystem access
- Built-in rudimentary unit testing support through assertions
The network layer of Node.js is low level while being simple to useāfor example, the HTTP modules allow you to write an HTTP server (or client) using a few lines of code. This is powerful, but it puts you, the programmer, very close to the protocol requests and makes you implement precisely those HTTP headers that you should return in request responses.
Typical web-application developers don't need to work at a low level of the HTTP or other protocols; instead, we tend to be more productive working with higher-level interfacesāfor example, PHP coders assume that Apache/Nginx/and so on are already there providing the HTTP, and that they don't have to implement the HTTP server portion of the stack. By contrast, a Node.js programmer does implement an HTTP server, to which their application code is attached.
To simplify the situation, the Node.js community has several web application frameworks, such as Express, providing the higher-level interfaces required by typical programmers. You can quickly configure an HTTP server with baked-in capabilities, such as sessions, cookies, serving static files, and logging, letting developers focus on their business logic. Other frameworks provide OAuth 2 support or focus on REST APIs, and so on.
The community of folks using Node.js has built an amazing variety of things on this foundation.
What are folks doing with Node.js?
Node.js is not limited to web service application development; the community around Node.js has taken it in many other directions:
- Build tools: Node.js has become a popular choice for developing command-line tools that are used in software development or communicating with service infrastructure. Grunt, Gulp, and Webpack are widely used by frontend developers to build assets for websites. Babel is widely used for transpiling modern ES-2016 code to run on older browsers. Popular CSS optimizers and processors, such as PostCSS, are written in Node.js. static website generation systems, such as Metalsmith, Punch, and AkashaCMS, run at the command line, and generate website content that you upload to a web server.
- Web UI testing: Puppeteer gives you control over a headless Chrome web-browser instance. With it, you can develop Node.js scripts by controlling a modern, full-featured web browser. Some typical use cases are web scraping and web application testing.
- Desktop applications: Both Electron and node-webkit (NW.js) are frameworks for developing desktop applications for Windows, macOS, and Linux. These frameworks utilize a large chunk of Chrome, wrapped by Node.js libraries, to develop desktop applications using web UI technologies. Applications are written with modern HTML5, CSS3, and JavaScript, and can utilize leading-edge web frameworks, such as Bootstrap, React, VueJS, and AngularJS. Many popular applications have been built using Electron, including the Slack desktop client application, the Atom, Microsoft Visual Code programming editors, the Postman REST client, the GitKraken GIT client, and Etcher, which makes it incredibly easy to burn OS images to flash drives to run on single-board computers.
- Mobile applications: The Node.js for Mobile Systems project lets you develop smartphone or tablet computer applications using Node.js for both iOS and Android. Apple's App Store rules preclude incorporating a JavaScript engine with JIT capabilities, meaning that normal Node.js cannot be used in an iOS application. For iOS application development, the project uses Node.js-on-ChakraCore to skirt around the App Store rules. For Android application development, the project uses regular Node.js on Android. At the time of writing, the project is in an early stage of development, but it looks promising.
- Internet of things (IoT): Node.js is a very popular language for Internet-of-Things projects, and Node.js runs on most ARM-based, single-board computers. The clearest example is the NodeRED project. It offers a graphical programming environment, letting you draw programs by connecting blocks together. It features hardware-oriented input and output mechanismsāfor example, to interact with General Purpose I/O (GPIO) pins on Raspberry Pi or Beaglebone single-board computers.
You may already be using Node.js applications without realizing it! JavaScript has a place outside the web browser, and it's not just thanks to Node.js.
Server-side JavaScript
Quit scratching your head, already! Of course, you're doing it, scratching your head and mumbling to yourself, "What's a browser language doing on the server?" In truth, JavaScript has a long and largely unknown history outside the browser. JavaScript is a program...