41,99 €
Get the best out of Node.js by mastering its most powerful components and patterns to create modular and scalable applications with ease
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.
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.
This book takes its intended readers through a comprehensive explanation to create a scalable and efficient real-time server-side apps.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 687
Veröffentlichungsjahr: 2016
Copyright © 2016 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: December 2014
Second edition: July 2016
Production reference: 1110716
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham B32PB, UK.
ISBN 978-1-78588-558-7
www.packtpub.com
Authors
Mario Casciaro
Luciano Mammino
Copy Editor
Safis Editing
Reviewers
Tane Piper
Joel Purra
Project Coordinator
Ulhas Kambali
Commissioning Editor
Amarabha Banerjee
Proofreader
Safis Editing
Acquisition Editor
Reshma Raman
Indexer
Mariammal Chettiyar
Content Development Editor
Onkar Wani
Graphics
Kirk D'Penha
Technical Editor
Prajakta Mhatre
Production Coordinator
Nilesh Mohite
Mario Casciaro is a software engineer and entrepreneur, passionate about technology, science and open source knowledge. Mario graduated with a master's degree in software engineering and started his professional career at IBM where he worked for several years on different enterprise products such as Tivoli Endpoint Manager, Cognos Insight, and SalesConnect. Next, he moved to D4H Technologies, a growing SaaS company, to lead the development of a new bleeding-edge product for managing emergency operations in real time. Currently, Mario is the co-founder and CEO of Sponsorama.com, a platform to help online projects raise funds through corporate sponsorship.
Mario is also the author of the first edition of Node.js Design Patterns.
When I was working on the first edition of this book I would never have thought it would become such a success. My biggest thanks go to all the readers of the first edition of this book, to those who bought it, to those who left a review, and to those who recommended it to their friends on Twitter or on other online forums. And of course, my gratitude also goes to the readers of this second edition; to you who are reading these words, you make all our efforts worthwhile. I also want you to join me in congratulating my friend Luciano, the co-author of this second edition, who did a tremendous job updating and adding new invaluable content to this book. All the merit goes to him as I only had the role of adviser in this second edition. Working on a book is not an easy task, but Luciano impressed me and all the staff at Packt for his dedication, professionalism, and technical skills, demonstrating he can achieve any goal he sets his mind to. It was a pleasure and a honor working with Luciano and I'm looking forward to other great collaborations. I also want to thank all the people who worked on the book, the folks of Packt, the technical reviewers (Tane and Joel) and all the friends who provided valuable suggestions and insights: Anton Whalley (@dhigit9), Alessandro Cinelli (@cirpo), Andrea Giuliano (@bit_shark), and Andrea Mangano (@ManganoAndrea). Thanks to all the friends who give me unconditional love, to my family, and most importantly to my girlfriend Miriam, the partner of all my adventures, who brings love and joy in every day of my life. There are still a hundred thousand adventures awaiting us.
Luciano Mammino is a software engineer born in 1987, the same year that the Nintendo released Super Mario Bros in Europe, which by chance is his favorite video-game. He started coding at the age of 12 using his father's old Intel 386, provided only with the DOS operating system and the qBasic interpreter.
After a master's degree in computer science he developed his programming skills mostly as a web developer working mainly as freelancer for companies and startups all around Italy. After a start-up parenthesis of 3 years as CTO and co-founder of Sbaam.com in Italy and in Ireland, he decided to relocate in Dublin to work as senior PHP engineer at Smartbox.
He loves developing open source libraries and working with frameworks such as Symfony and Express. He is convinced that the JavaScript fame is still at the very beginning and that this technology will have a huge impact in the future of most of the web-and mobile-related technologies. For this reason, he spends most of his free time improving his knowledge of JavaScript and playing with Node.js.
The first huge thanks go to Mario for giving me the opportunity and the trust to work alongside him on the new edition of this book. It was an amazing experience and hopefully just the beginning of a long series of collaborations.
This book was only possible thanks to the incredible and efficient work of the Packt team, especially thanks to the relentless efforts and the patience of Onkar, Reshma, and Prajakta. Also thanks to the reviewers Tane Piper and Joel Purra, their experience with Node.js was crucial to raise the quality of the content provided in this book.
A great hug (and many beers) go to my friends Anton Whalley (@dhigit9), Alessandro Cinelli (@cirpo), Andrea Giuliano (@bit_shark), and Andrea Mangano (@ManganoAndrea) for encouraging me all along the way, for sharing with me their experience as developers and for providing meaningful insights on the contents of this book.
Another great thank you goes to Ricardo, Jose, Alberto, Marcin, Nacho, David, Arthur, and all my colleagues at Smartbox for making me love my days at work and for inspiring and motivating me to get better every day as a software engineer. I couldn't ask for a better team.
My deepest gratitude goes to my family, who raised and sustained me in every possible way along my journey. Thanks, mom, for being a constant source of inspiration and strength in my life. Thanks, dad, for all the lessons, the encouragement and the advice, I really miss talking with you, I really miss you. Thanks to my brother Davide and my sister Alessia for being present in the painful and the joyful moments and making me feel part of a great family.
Thanks to Franco and his family for supporting many of my initiatives and for sharing their wisdom and life experience with me.
Kudos to my "nerd" friends Gianluca, Flavio, Antonio, Valerio, and Luca for the great time together and for constantly encouraging me to keep working on this book.
Also kudos to my "less nerdy" friends Damiano, Pietro, and Sebastiano for their friendship and all the laughs and the fun we have when we hang out together in Dublin.
Last, but definitely not least, thanks to my girlfriend Francesca. Thank you for the unconditioned love and for supporting me on every adventure, even the craziest ones. I really look forward to writing the next pages in the book of our life with you.
Tane Piper is a full stack developer based in London, UK. For over 10 years He has worked for several agencies and companies delivering software in a variety of languages such as Python, PHP, and JavaScript. He has been working with Node.js since 2010 and was one of the first people talking about server-side JavaScript in the UK and Ireland with several talks in 2011/2012. He was also an early contributor to, and advocate for the jQuery project. Currently he works at a consultancy in London delivering innovative solutions and is mostly writing React and Node applications. Outside of his professional work he is a keen scuba diver and amateur photographer.
I would personally like to thank my girlfriend Elina who has turned my life around in the last two years and encouraged me to take up the task of reviewing this book.
Joel Purra started toying around with computers even before he was in his teens, seeing them as another kind of a video game device. It was not long before he took apart (sometimes broke and subsequently fixed) any computer he came across while playing the latest games on them. It was gaming that led him to discover programming in his early teens when modifying a Lunar Lander game triggered an interest in creating digital tools. Soon after getting an Internet connection at home, he developed his first e-commerce website, and thus his business started; it launched his career at an early age. At the age of 17, Joel started studying computer programming and an energy science program at a nuclear power plant's school. After graduation, he studied to become a second lieutenant telecommunications specialist in the Swedish Army before moving on to study for his master's of science degree in information technology and engineering at Linköping University. He has been involved in start-ups and other companies—both successful and unsuccessful—since 1998, and he has been a consultant since 2007. Born, raised, and educated in Sweden, Joel also enjoys the flexible lifestyle of a freelance developer, having traveled through five continents with his backpack and lived abroad for several years. A learner constantly looking for challenges, one of his goals is to build and evolve software for broad public use. You can visit his website at http://joelpurra.com/.
I'd like to thank the open source community for providing the building blocks necessary to compose both small and large software systems even as a freelance consultant. Nanos gigantum humeris insidentes. Remember to commit early, commit often!
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www2.packtpub.com/books/subscription/packtlib
Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can search, access, and read Packt's entire library of books.
Node.js is considered by many as a game-changer—the biggest shift of the decade in web development. It is loved not just for its technical capabilities, but also for the paradigm shift that it introduced in web development.
First, Node.js applications are written in JavaScript, the language of the web, the only programming language supported natively by a majority of web browsers. This aspect enables scenarios such as single-language application stacks and sharing of code between the server and the client. Node.js itself is contributing to the rise and evolution of the JavaScript language. People realize that using JavaScript on the server is not as bad as it is in the browser, and they will soon start to love it for its pragmatism and for its hybrid nature, halfway between object-oriented and functional programming.
The second revolutionizing factor is its single-threaded, asynchronous architecture. Besides obvious advantages from a performance and scalability point of view, this characteristic changed the way developers approach concurrency and parallelism. Mutexes are replaced by queues, threads by callbacks and events, and synchronization by causality.
The last and most important aspect of Node.js lies in its ecosystem: the npm package manager, its constantly growing database of modules, its enthusiastic and helpful community, and most importantly, its very own culture based on simplicity, pragmatism, and extreme modularity.
However, because of these peculiarities, Node.js development gives you a very different feel compared to the other server-side platforms, and any developer new to this paradigm will often feel unsure about how to tackle even the most common design and coding problem effectively. Common questions include: "How do I organize my code?", "What's the best way to design this?", "How can I make my application more modular?", "How do I handle a set of asynchronous calls effectively?", "How can I make sure that my application will not collapse while it grows?", or more simply "What's the right way of doing this?" Fortunately, Node.js has become a mature enough platform and most of these questions can now be easily answered with a design pattern, a proven coding technique, or a recommended practice. The aim of this book is to guide you through this emerging world of patterns, techniques, and practices, showing you what the proven solutions to the common problems are and teaching you how to use them as the starting point to building the solution to your particular problem.
By reading this book, you will learn the following:
How to use the right point of view when approaching a Node.js design problem. You will learn, for example, how different traditional design patterns look in Node.js, or how to design modules that do only one thing.
A set of patterns to solve common Node.js design and coding problems:You will be presented with a "Swiss army knife" of patterns, ready-to-use in order to efficiently solve your everyday development and design problems.
How to write modular and efficient Node.js applications:You will gain an understanding of the basic building blocks and principles of writing large and well-organized Node.js applications and you will be able to apply these principles to novel problems that don't fall within the scope of existing patterns.
Throughout the book, you will be presented with several real-life libraries and technologies, such as LevelDb, Redis, RabbitMQ, ZMQ, Express, and many others. They will be used to demonstrate a pattern or technique, and besides making the example more useful, these will also give you great exposure to the Node.js ecosystem and its set of solutions.
Whether you use or plan to use Node.js for your work, your side project, or for an open source project, recognizing and using well-known patterns and techniques will allow you to use a common language when sharing your code and design, and on top of that, it will help you get a better understanding of the future of Node.js and how to make your own contributions a part of it.
Chapter 1, Welcome to the Node.js Platform, serves as an introduction to the world of Node.js application design by showing the patterns at the core of the platform itself. It covers the Node.js ecosystem and its philosophy, a short introduction to Node.js version 6, ES2015, and the reactor pattern.
Chapter 2, Node.js Essential Patterns, introduces the first steps towards asynchronous coding and design patterns with Node.js discussing and comparing callbacks and the event emitter (observer pattern). This chapter also introduces the Node.js module system and the related module pattern.
Chapter 3, Asynchronous Control Flow Patterns with Callbacks, introduces a set of patterns and techniques for efficiently handling asynchronous control flow in Node.js. This chapter teaches you how to mitigate the "callback hell" problem using plain JavaScript and the async library.
Chapter 4, Asynchronous Control Flow Patterns with ES2015 and Beyond, progresses with the exploration of asynchronous control flows introducing Promises, Generators, and Async-Await.
Chapter 5, Coding with Streams, dives deep into one of the most important patterns in Node.js: streams. It shows you how to process data with transform streams and how to combine them into different layouts.
Chapter 6, Design Patterns, deals with a controversial topic: traditional design patterns in Node.js. It covers the most popular conventional design patterns and shows you how unconventional they might look in Node.js. It also introduces the reader to some emerging design patterns that are specific only to JavaScript and Node.js.
Chapter 7, Wiring Modules, analyzes the different solutions for linking the modules of an application together. In this chapter, you will learn design patterns such as Dependency Injection and service locator.
Chapter 8, Universal JavaScript for Web Applications, explores one of the most interesting capabilities of modern JavaScript web applications: being able to share application code between the frontend and the backend. Across this chapter we learn the basic principles of Universal JavaScript by building a simple web application with React, Webpack, and Babel.
Chapter 9, Advanced Asynchronous Recipes, takes a problem-solution approach to show you how some common coding and design challenges can be solved with ready-to-use solutions.
Chapter 10, Scalability and Architectural Patterns, teaches you the basic techniques and patterns for scaling a Node.js application.
Chapter 11, Messaging and Integration Patterns, presents the most important messaging patterns, teaching you how to build and integrate complex distributed systems using ZMQ and AMQP.
To experiment with the code, you will need a working installation of Node.js version 6 (or greater) and npm 3 (or greater). Some examples will require you to use a transpiler such as Babel. You will also need to be familiar with the command prompt, know how to install an npm package, and know how to run Node.js applications. You will also need a text editor to work with the code and a modern web browser.
This book is for developers who have already had initial contact with Node.js and now want to get the most out of it in terms of productivity, design quality, and scalability. You are only required to have some prior exposure to the technology through some basic examples, since this book will cover some basic concepts as well. Developers with intermediate experience in Node.js will also find the techniques presented in this book beneficial.
Some background in software design theory is also an advantage to understand some of the concepts presented.
This book assumes that you have a working knowledge of web application development, JavaScript, web services, databases, and data structures.
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book 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 files e-mailed directly to you.
You can download the code files by following these steps:
You can also download the code files by clicking on the Code Files button on the book's webpage at the Packt Publishing website. This page can be accessed by entering the book's name in the Search box. Please note that you need to be logged into your Packt account. Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
The code bundle for the book is also hosted on GitHub at http://bit.ly/node_book_code. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at [email protected] with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
Some principles and design patterns literally define developer experience with the Node.js platform and its ecosystem; the most peculiar ones are probably its asynchronous nature and its programming style that, in its simplest incarnation, make heavy use of callbacks. It's important that we first dive into these fundamental principles and patterns, not only for writing correct code, but also to be able to take effective design decisions when it comes to solving bigger and more complex problems.
Another aspect that characterizes Node.js is its philosophy. Approaching Node.js is in fact way more than simply learning a new technology; it's also embracing a culture and a community. We will see how this greatly influences the way we design our applications and components, and the way they interact with those created by the community.
In addition to these aspects, it's worth knowing that the latest versions of Node.js introduced support for many of the features described by ES2015 (formerly ES6), which makes the language even more expressive and enjoyable to use. It is important to embrace these new syntactic and functional additions to the language in order to be able to produce more concise and readable code and come up with alternative ways to implement the design patterns that we are going to see throughout this book.
In this chapter, we will learn the following topics:
Every platform has its own philosophy—a set of principles and guidelines that are generally accepted by the community, an ideology of doing things that influences the evolution of a platform, and how applications are developed and designed. Some of these principles arise from the technology itself, some of them are enabled by its ecosystem, some are just trends in the community, and others are evolutions of different ideologies. In Node.js, some of these principles come directly from its creator, Ryan Dahl; from all the people who contributed to the core; from charismatic figures in the community; and some of the principles are inherited from the JavaScript culture or are influenced by the Unix philosophy.
None of these rules are imposed and they should always be applied with common sense; however, they can prove to be tremendously useful when we are looking for a source of inspiration while designing our programs.
You can find an extensive list of software development philosophies on Wikipedia at http://en.wikipedia.org/wiki/List_of_software_development_philosophies.
The Node.js core itself has its foundations built on a few principles; one of these is having the smallest set of functionalities, leaving the rest to the so-called userland (or userspace), the ecosystem of modules living outside the core. This principle has an enormous impact on the Node.js culture, as it gives freedom to the community to experiment and iterate quickly on a broader set of solutions within the scope of the userland modules, instead of being imposed with one slowly evolving solution that is built into the more tightly controlled and stable core. Keeping the core set of functionalities to the bare minimum, then, not only becomes convenient in terms of maintainability, but also in terms of the positive cultural impact that it brings on the evolution of the entire ecosystem.
Node.js uses the concept of a module as a fundamental means to structure the code of a program. It is the building block for creating applications and reusable libraries called packages (a package is also frequently referred to as a module since, usually, it has one single module as an entry point). In Node.js, one of the most evangelized principles is to design small modules, not only in terms of code size, but most importantly in terms of scope.
This principle has its roots in the Unix philosophy, particularly in two of its precepts, which are as follows:
Node.js brought these concepts to a whole new level. Along with the help of npm, the official package manager, Node.js helps solve the dependency hell problem by making sure that each installed package will have its own separate set of dependencies, thus enabling a program to depend on a lot of packages without incurring conflicts. The Node way, in fact, involves extreme levels of reusability, whereby applications are composed of a high number of small, well-focused dependencies. While this can be considered unpractical or even totally unfeasible in other platforms, in Node.js this practice is encouraged. As a consequence, it is not rare to find npm packages containing less than 100 lines of code or exposing only one single function.
Besides the clear advantage in terms of reusability, a small module is also considered to be the following:
Having smaller and more focused modules empowers everyone to share or reuse even the smallest piece of code; it's the Don't Repeat Yourself (DRY) principle applied to a whole new level.
In addition to being small in size and scope, Node.js modules usually also have the characteristic of exposing a minimal set of functionalities. The main advantage here is increased usability of the API, which means that the API becomes clearer to use and is less exposed to erroneous usage. Most of the time, in fact, the user of a component is only interested in a very limited and focused set of features, without the need to extend its functionality or tap into more advanced aspects.
In Node.js, a very common pattern for defining modules is to expose only one piece of functionality, such as a function or a constructor, while letting more advanced aspects or secondary features become properties of the exported function or constructor. This helps the user to identify what is important and what is secondary. It is not rare to find modules that expose only one function and nothing else, for the simple fact that it provides a single, unmistakably clear entry point.
Another characteristic of many Node.js modules is the fact that they are created to be used rather than extended. Locking down the internals of a module by forbidding any possibility of an extension might sound inflexible, but it actually has the advantage of reducing the use cases, simplifying its implementation, facilitating its maintenance, and increasing its usability.
Have you ever heard of the Keep It Simple, Stupid (KISS) principle or the famous quote:
"Simplicity is the ultimate sophistication."
--Leonardo da VinciRichard P. Gabriel, a prominent computer scientist, coined the term "worse is better" to describe the model, whereby less and simpler functionality is a good design choice for software. In his essay, The Rise of "Worse is Better", he says:
"The design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design."
Designing simple, as opposed to perfect, fully-featured software, is a good practice for several reasons: it takes less effort to implement, allows faster shipping with fewer resources, is easier to adapt, and is easier to maintain and understand. These factors foster community contributions and allow the software itself to grow and improve.
In Node.js, this principle is also enabled by JavaScript, which is a very pragmatic language. It's not rare, in fact, to see simple functions, closures, and object literals replacing complex class hierarchies. Pure object-oriented designs often try to replicate the real world using the mathematical terms of a computer system without considering the imperfection and the complexity of the real world itself. The truth is that; our software is always an approximation of reality, and we would probably have more success in trying to get something working sooner and with reasonable complexity, instead of trying to create near-perfect software with huge effort and tons of code to maintain.
Throughout this book, we will see this principle in action many times. For example, a considerable number of traditional design patterns, such as singleton or decorator, can have a trivial, even if sometimes not foolproof, implementation and we will see how an uncomplicated, practical approach (most of the time) is preferred to a pure, flawless design.
