O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Node.js Design Patterns - Second Edition

Book Description

Get the best out of Node.js by mastering its most powerful components and patterns to create modular and scalable applications with ease

About This Book

  • Create reusable patterns and modules by leveraging the new features of Node.js .

  • Understand the asynchronous single thread design of node and grasp all its features and patterns to take advantage of various functions.

  • This unique guide will help you get the most out of Node.js and its ecosystem.

  • Who This Book Is For

    The book is meant for developers and software architects with a basic working knowledge of JavaScript who are interested in acquiring a deeper understanding of how to design and develop enterprise-level Node.js applications.

    Basic knowledge of Node.js is also helpful to get the most out of this book.

    What You Will Learn

  • Design and implement a series of server-side JavaScript patterns so you understand why and when to apply them in different use case scenarios

  • Become comfortable with writing asynchronous code by leveraging constructs such as callbacks, promises, generators and the async-await syntax

  • Identify the most important concerns and apply unique tricks to achieve higher scalability and modularity in your Node.js application

  • Untangle your modules by organizing and connecting them coherently

  • Reuse well-known techniques to solve common design and coding issues

  • Explore the latest trends in Universal JavaScript, learn how to write code that runs on both Node.js and the browser and leverage React and its ecosystem to implement universal applications

  • In Detail

    Node.js is a massively popular software platform that lets you use JavaScript to easily create scalable server-side applications. It allows you to create efficient code, enabling a more sustainable way of writing software made of only one language across the full stack, along with extreme levels of reusability, pragmatism, simplicity, and collaboration. Node.js is revolutionizing the web and the way people and companies create their software.

    In this book, we will take you on a journey across various ideas and components, and the challenges you would commonly encounter while designing and developing software using the Node.js platform. You will also discover the "Node.js way" of dealing with design and coding decisions.

    The book kicks off by exploring the basics of Node.js describing it's asynchronous single-threaded architecture and the main design patterns. It then shows you how to master the asynchronous control flow patterns,and the stream component and it culminates into a detailed list of Node.js implementations of the most common design patterns as well as some specific design patterns that are exclusive to the Node.js world.Lastly, it dives into more advanced concepts such as Universal Javascript, and scalability' and it's meant to conclude the journey by giving the reader all the necessary concepts to be able to build an enterprise grade application using Node.js.

    Style and approach

    This book takes its intended readers through a comprehensive explanation to create a scalable and efficient real-time server-side apps.

    Downloading the example code for this book. You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the code file.

    Table of Contents

    1. Node.js Design Patterns - Second Edition
      1. Node.js Design Patterns - Second Edition
      2. Credits
      3. About the Authors
      4. Acknowledgments
      5. About the Author
      6. Acknowledgments
      7. About the Reviewers
      8. www.PacktPub.com
        1. eBooks, discount offers, and more
          1. Why subscribe?
      9. Preface
        1. What this book covers
        2. What you need for this book
        3. Who this book is for
        4. Conventions
        5. Reader feedback
        6. Customer support
          1. Downloading the example code
          2. Errata
          3. Piracy
          4. Questions
      10. 1. Welcome to the Node.js Platform
        1. The Node.js philosophy
          1. Small core
          2. Small modules
          3. Small surface area
          4. Simplicity and pragmatism
        2. Introduction to Node.js 6 and ES2015
          1. The let and const keywords
          2. The arrow function
          3. Class syntax
          4. Enhanced object literals
          5. Map and Set collections
          6. WeakMap and WeakSet collections
          7. Template literals
          8. Other ES2015 features
        3. The reactor pattern
          1. I/O is slow
          2. Blocking I/O
          3. Non-blocking I/O
          4. Event demultiplexing
          5. Introducing the reactor pattern
          6. The non-blocking I/O engine of Node.js-libuv
          7. The recipe for Node.js
        4. Summary
      11. 2. Node.js Essential Patterns
        1. The callback pattern
          1. The continuation-passing style
            1. Synchronous continuation-passing style
            2. Asynchronous continuation-passing style
            3. Non-continuation-passing style callbacks
          2. Synchronous or asynchronous?
            1. An unpredictable function
            2. Unleashing Zalgo
            3. Using synchronous APIs
            4. Deferred execution
          3. Node.js callback conventions
            1. Callbacks come last
            2. Error comes first
            3. Propagating errors
            4. Uncaught exceptions
        2. The module system and its patterns
          1. The revealing module pattern
          2. Node.js modules explained
            1. A homemade module loader
            2. Defining a module
            3. Defining globals
            4. module.exports versus exports
            5. The require function is synchronous
            6. The resolving algorithm
            7. The module cache
            8. Circular dependencies
          3. Module definition patterns
            1. Named exports
            2. Exporting a function
            3. Exporting a constructor
            4. Exporting an instance
            5. Modifying other modules or the global scope
        3. The observer pattern
          1. The EventEmitter class
          2. Creating and using EventEmitter
          3. Propagating errors
          4. Making any object observable
          5. Synchronous and asynchronous events
          6. EventEmitter versus callbacks
          7. Combining callbacks and EventEmitter
        4. Summary
      12. 3. Asynchronous Control Flow Patterns with Callbacks
        1. The difficulties of asynchronous programming
          1. Creating a simple web spider
          2. The callback hell
        2. Using plain JavaScript
          1. Callback discipline
          2. Applying the callback discipline
          3. Sequential execution
            1. Executing a known set of tasks in sequence
            2. Sequential iteration
              1. Web spider version 2
              2. Sequential crawling of links
              3. The pattern
          4. Parallel execution
            1. Web spider version 3
            2. The pattern
            3. Fixing race conditions with concurrent tasks
          5. Limited parallel execution
            1. Limiting the concurrency
            2. Globally limiting the concurrency
              1. Queues to the rescue
              2. Web spider version 4
        3. The async library
          1. Sequential execution
            1. Sequential execution of a known set of tasks
            2. Sequential iteration
          2. Parallel execution
          3. Limited parallel execution
        4. Summary
      13. 4. Asynchronous Control Flow Patterns with ES2015 and Beyond
        1. Promise
          1. What is a promise?
          2. Promises/A+ implementations
          3. Promisifying a Node.js style function
          4. Sequential execution
            1. Sequential iteration
            2. Sequential iteration – the pattern
          5. Parallel execution
          6. Limited parallel execution
          7. Exposing callbacks and promises in public APIs
        2. Generators
          1. The basics of generators
            1. A simple example
            2. Generators as iterators
            3. Passing values back to a generator
          2. Asynchronous control flow with generators
            1. Generator-based control flow using co
          3. Sequential execution
          4. Parallel execution
          5. Limited parallel execution
            1. Producer-consumer pattern
            2. Limiting the download tasks concurrency
        3. Async await using Babel
          1. Installing and running Babel
        4. Comparison
        5. Summary
      14. 5. Coding with Streams
        1. Discovering the importance of streams
          1. Buffering versus streaming
          2. Spatial efficiency
            1. Gzipping using a buffered API
            2. Gzipping using streams
          3. Time efficiency
          4. Composability
        2. Getting started with streams
          1. Anatomy of streams
          2. Readable streams
            1. Reading from a stream
              1. The non-flowing mode
              2. Flowing mode
            2. Implementing Readable streams
          3. Writable streams
            1. Writing to a stream
            2. Back-pressure
            3. Implementing Writable streams
          4. Duplex streams
          5. Transform streams
            1. Implementing Transform streams
          6. Connecting streams using pipes
            1. Through and from for working with streams
        3. Asynchronous control flow with streams
          1. Sequential execution
          2. Unordered parallel execution
            1. Implementing an unordered parallel stream
            2. Implementing a URL status monitoring application
          3. Unordered limited parallel execution
            1. Ordered parallel execution
        4. Piping patterns
          1. Combining streams
            1. Implementing a combined stream
          2. Forking streams
            1. Implementing a multiple checksum generator
          3. Merging streams
            1. Creating a tarball from multiple directories
          4. Multiplexing and demultiplexing
            1. Building a remote logger
              1. Client side – multiplexing
              2. Server side – demultiplexing
              3. Running the mux/demux application
            2. Multiplexing and demultiplexing object streams
        5. Summary
      15. 6. Design Patterns
        1. Factory
          1. A generic interface for creating objects
          2. A mechanism to enforce encapsulation
          3. Building a simple code profiler
          4. Composable factory functions
          5. In the wild
        2. Revealing constructor
          1. A read-only event emitter
          2. In the wild
        3. Proxy
          1. Techniques for implementing proxies
            1. Object composition
            2. Object augmentation
          2. A comparison of the different techniques
          3. Creating a logging Writable stream
          4. Proxy in the ecosystem – function hooks and AOP
          5. ES2015 Proxy
          6. In the wild
        4. Decorator
          1. Techniques for implementing Decorators
            1. Composition
            2. Object augmentation
          2. Decorating a LevelUP database
            1. Introducing LevelUP and LevelDB
            2. Implementing a LevelUP plugin
          3. In the wild
        5. Adapter
          1. Using LevelUP through the filesystem API
          2. In the wild
        6. Strategy
          1. Multi-format configuration objects
          2. In the wild
        7. State
          1. Implementing a basic fail-safe socket
        8. Template
          1. A configuration manager template
          2. In the wild
        9. Middleware
          1. Middleware in Express
          2. Middleware as a pattern
          3. Creating a middleware framework for ØMQ
            1. The Middleware Manager
            2. A middleware to support JSON messages
            3. Using the ØMQ middleware framework
              1. The server
              2. The client
          4. Middleware using generators in Koa
        10. Command
          1. A flexible pattern
            1. The task pattern
            2. A more complex command
        11. Summary
      16. 7. Wiring Modules
        1. Modules and dependencies
          1. The most common dependency in Node.js
          2. Cohesion and coupling
          3. Stateful modules
            1. The Singleton pattern in Node.js
        2. Patterns for wiring modules
          1. Hardcoded dependency
            1. Building an authentication server using hardcoded dependencies
              1. The db module
              2. The authService module
              3. The authController module
              4. The app module
              5. Running the authentication server
            2. Pros and cons of hardcoded dependencies
          2. Dependency Injection
            1. Refactoring the authentication server to use DI
            2. The different types of DI
            3. Pros and cons of DI
          3. Service locator
            1. Refactoring the authentication server to use a service locator
            2. Pros and cons of a service locator
          4. Dependency Injection container
            1. Declaring a set of dependencies to a DI container
            2. Refactoring the authentication server to use a DI container
            3. Pros and cons of a DI container
        3. Wiring plugins
          1. Plugins as packages
          2. Extension points
          3. Plugin-controlled vs application-controlled extension
          4. Implementing a logout plugin
            1. Using hardcoded dependencies
            2. Exposing services using a service locator
            3. Exposing services using DI
            4. Exposing services using a DI container
        4. Summary
      17. 8. Universal JavaScript for Web Applications
        1. Sharing code with the browser
          1. Sharing modules
            1. Universal Module Definition
              1. Creating an UMD module
              2. Considerations on the UMD pattern
            2. ES2015 modules
        2. Introducing Webpack
          1. Exploring the magic of Webpack
          2. The advantages of using Webpack
          3. Using ES2015 with Webpack
        3. Fundamentals of cross-platform development
          1. Runtime code branching
          2. Build-time code branching
          3. Module swapping
          4. Design patterns for cross-platform development
        4. Introducing React
          1. First React component
          2. JSX, what?!
          3. Configuring Webpack to transpile JSX
          4. Rendering in the browser
          5. The React Router library
        5. Creating a Universal JavaScript app
          1. Creating reusable components
          2. Server-side rendering
          3. Universal rendering and routing
          4. Universal data retrieval
            1. The API server
            2. Proxying requests for the frontend
            3. Universal API client
            4. Asynchronous React components
            5. The web server
        6. Summary
      18. 9. Advanced Asynchronous Recipes
        1. Requiring asynchronously initialized modules
          1. Canonical solutions
          2. Preinitialization queues
            1. Implementing a module that initializes asynchronously
            2. Wrapping the module with preinitialization queues
          3. In the wild
        2. Asynchronous batching and caching
          1. Implementing a server with no caching or batching
          2. Asynchronous request batching
            1. Batching requests in the total sales web server
          3. Asynchronous request caching
            1. Caching requests in the total sales web server
            2. Notes about implementing caching mechanisms
          4. Batching and caching with promises
        3. Running CPU-bound tasks
          1. Solving the subset sum problem
          2. Interleaving with setImmediate
            1. Interleaving the steps of the subset sum algorithm
            2. Considerations on the interleaving pattern
          3. Using multiple processes
            1. Delegating the subset sum task to other processes
              1. Implementing a process pool
              2. Communicating with a child process
              3. Communicating with the parent process
            2. Considerations on the multiprocess pattern
        4. Summary
      19. 10. Scalability and Architectural Patterns
        1. An introduction to application scaling
          1. Scaling Node.js applications
          2. The three dimensions of scalability
        2. Cloning and load balancing
          1. The cluster module
            1. Notes on the behavior of the cluster module
            2. Building a simple HTTP server
            3. Scaling with the cluster module
            4. Resiliency and availability with the cluster module
            5. Zero-downtime restart
          2. Dealing with stateful communications
            1. Sharing the state across multiple instances
            2. Sticky load balancing
          3. Scaling with a reverse proxy
            1. Load balancing with Nginx
          4. Using a service registry
            1. Implementing a dynamic load balancer with http-proxy and Consul
          5. Peer-to-peer load balancing
            1. Implementing an HTTP client that can balance requests across multiple servers
        3. Decomposing complex applications
          1. Monolithic architecture
          2. The microservice architecture
            1. An example of microservice architecture
            2. Pros and cons of microservices
              1. Every service is expendable
              2. Reusability across platforms and languages
              3. A way to scale the application
              4. The challenges of microservices
          3. Integration patterns in a microservice architecture
            1. The API proxy
            2. API orchestration
            3. Integration with a message broker
        4. Summary
      20. 11. Messaging and Integration Patterns
        1. Fundamentals of a messaging system
          1. One-way and request/reply patterns
          2. Message types
            1. Command Message
            2. Event Message
            3. Document Message
          3. Asynchronous messaging and queues
          4. Peer-to-peer or broker-based messaging
        2. Publish/subscribe pattern
          1. Building a minimalist real-time chat application
            1. Implementing the server side
            2. Implementing the client side
            3. Running and scaling the chat application
          2. Using Redis as a message broker
          3. Peer-to-peer publish/subscribe with ØMQ
            1. Introducing ØMQ
            2. Designing a peer-to-peer architecture for the chat server
            3. Using the ØMQ PUB/SUB sockets
          4. Durable subscribers
            1. Introducing AMQP
            2. Durable subscribers with AMQP and RabbitMQ
              1. Designing a history service for the chat application
              2. Implementing a reliable history service using AMQP
              3. Integrating the chat application with AMQP
        3. Pipelines and task distribution patterns
          1. The ØMQ fanout/fanin pattern
            1. PUSH/PULL sockets
            2. Building a distributed hashsum cracker with ØMQ
              1. Implementing the ventilator
              2. Implementing the worker
              3. Implementing the sink
              4. Running the application
          2. Pipelines and competing consumers in AMQP
            1. Point-to-point communications and competing consumers
            2. Implementing the hashsum cracker using AMQP
              1. Implementing the producer
              2. Implementing the worker
              3. Implementing the result collector
              4. Running the application
        4. Request/reply patterns
          1. Correlation identifier
            1. Implementing a request/reply abstraction using correlation identifiers
              1. Abstracting the request
              2. Abstracting the reply
              3. Trying the full request/reply cycle
          2. Return address
            1. Implementing the return address pattern in AMQP
              1. Implementing the request abstraction
              2. Implementing the reply abstraction
              3. Implementing the requestor and the replier
        5. Summary