Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ishtms/learn-nodejs-hard-way

Learn NodeJS and master the art of server-side programming by creating a backend framework with 0 dependencies.
https://github.com/ishtms/learn-nodejs-hard-way

api backend backend-development book coding javascript learn learn-to-code learning learning-by-doing learning-exercise node nodejs programming programming-fundamentals server training-materials

Last synced: 2 days ago
JSON representation

Learn NodeJS and master the art of server-side programming by creating a backend framework with 0 dependencies.

Awesome Lists containing this project

README

        

# Learn Node.js by building a backend framework - [Velocy](https://github.com/ishtms/velocy)


Learn nodejs the hard way

You can access the current version of the book in the [chapters directory](/chapters) or in PDF format (both Light and Dark modes are available) by [clicking here](https://github.com/ishtms/learn-nodejs-hard-way/releases). Note that this version includes the current release of the content, and is not the final version.

> This book is still in a very early stage. It contains an insignificant portion of the total content that the book is supposed to cover. There’s going to be 0 dependencies for our [backend framework](https://github.com/ishtms/velocy), as well as our [logging library](https://github.com/ishtms/logtar). Everything will be done using vanilla Node.js, the hard-way (the best way to learn).

---

## Note

If you're not familiar with javascript, you may also check out my other repository - [Learn Javascript - The Easy Way](https://github.com/ishtms/learn-javascript-easy-way) that takes you on a deep and a fun journey into Javascript - from the very basics to the advanced concepts that you'd ever need, without diving into too much theory. Only practical code examples.

---

To master a new concept, it's often best to begin from the ground up. This isn't just another Node.js guide; it's a comprehensive, code-along experience aimed at building a real world product that may be used by thousands of developers. The product that we're going to build will be a backend framework, that too from scratch.

You won't just learn how Node.js works, but also why it operates in a particular way. The guide also includes discussions on relevant data structures and design patterns.

The book also includes a wide range of exercises specifically created to challenge you, that may require commitment and consistent effort on your part. The first exercises start from [chapter 7](/chapters/ch06.5-ex-implementing-a-trie.md)

This guide goes beyond the basics. We're focused on delivering a modular, optimized backend framework that is close to being production-ready. Topics like performance optimization, security measures, and various testing approaches will be covered to ensure the framework is both reliable and extendable.

I highly recommend actively coding alongside this guide, rather than just reading through it, for a full understanding of Node.js and its more intricate aspects.

The repo for our backend framework- [Velocy](https://github.com/ishtms/velocy). (W.I.P)

[![Read Next](/assets/imgs/next.png)](/chapters/ch01.0-what-is-a-web-server-anyway.md)

# Table of contents

- [(Optional) Node.js is way faster than you think](chapters/ch00-nodejs-faster-than-you-think.md#-optional-node-js-is-way-faster-than-you-think)
- [Contenders for the test](chapters/ch00-nodejs-faster-than-you-think.md#contenders-for-the-test)
- [Elysia - Bun](chapters/ch00-nodejs-faster-than-you-think.md#elysia-bun)
- [Axum - Rust](chapters/ch00-nodejs-faster-than-you-think.md#axum-rust)
- [Express - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#express-node-js)
- [Velocy - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#velocy-node-js)
- [The benchmark](chapters/ch00-nodejs-faster-than-you-think.md#the-benchmark)
- [Source code](chapters/ch00-nodejs-faster-than-you-think.md#source-code)
- [Elysia - Bun](chapters/ch00-nodejs-faster-than-you-think.md#elysia-bun)
- [Axum - Rust](chapters/ch00-nodejs-faster-than-you-think.md#axum-rust)
- [Express - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#express-node-js)
- [Velocy - Node.js](chapters/ch00-nodejs-faster-than-you-think.md#velocy-node-js)
- [Results - Typical benchmark](chapters/ch00-nodejs-faster-than-you-think.md#results-typical-benchmark)
- [Result: Elysia - Bun/Zig (149,047 req/s)](chapters/ch00-nodejs-faster-than-you-think.md#result-elysia-bun-zig-149-047-req-s-)
- [Result: Axum - Rust (208,938 req/s)](chapters/ch00-nodejs-faster-than-you-think.md#result-axum-rust-208-938-req-s-)
- [Result: Express - Node.js (28,923 req/s)](chapters/ch00-nodejs-faster-than-you-think.md#result-express-node-js-28-923-req-s-)
- [Result: Velocy - Node.js (83,689)](chapters/ch00-nodejs-faster-than-you-think.md#result-velocy-node-js-83-689-)
- [Graphs](chapters/ch00-nodejs-faster-than-you-think.md#graphs)
- [Latency](chapters/ch00-nodejs-faster-than-you-think.md#latency)
- [Requests/sec](chapters/ch00-nodejs-faster-than-you-think.md#requests-sec)
- [Idle memory](chapters/ch00-nodejs-faster-than-you-think.md#idle-memory)
- [Memory under constant load](chapters/ch00-nodejs-faster-than-you-think.md#memory-under-constant-load)
- [Verdict - Typical benchmark](chapters/ch00-nodejs-faster-than-you-think.md#verdict-typical-benchmark)
- [The real benchmark](chapters/ch00-nodejs-faster-than-you-think.md#the-real-benchmark)
- [Updating our code](chapters/ch00-nodejs-faster-than-you-think.md#updating-our-code)
- [Elysia](chapters/ch00-nodejs-faster-than-you-think.md#elysia)
- [Express](chapters/ch00-nodejs-faster-than-you-think.md#express)
- [Velocy](chapters/ch00-nodejs-faster-than-you-think.md#velocy)
- [Results - A real-world use-case](chapters/ch00-nodejs-faster-than-you-think.md#results-a-real-world-use-case)
- [Result: Express - Node (50,275 req/sec)](chapters/ch00-nodejs-faster-than-you-think.md#result-express-node-50-275-req-sec-)
- [Result: Velocy - Node (138,956 req/sec)](chapters/ch00-nodejs-faster-than-you-think.md#result-velocy-node-138-956-req-sec-)
- [Latency](chapters/ch00-nodejs-faster-than-you-think.md#latency)
- [Latency without `max latency` bar](chapters/ch00-nodejs-faster-than-you-think.md#latency-without-max-latency-bar)
- [Requests/sec](chapters/ch00-nodejs-faster-than-you-think.md#requests-sec)
- [Idle memory](chapters/ch00-nodejs-faster-than-you-think.md#idle-memory)
- [Memory under constant load](chapters/ch00-nodejs-faster-than-you-think.md#memory-under-constant-load)
- [Final Verdict](chapters/ch00-nodejs-faster-than-you-think.md#final-verdict)
- [What the heck is a web server any way?](chapters/ch01.0-what-is-a-web-server-anyway.md#what-the-heck-is-a-web-server-any-way-)
- [Parts of a Web Server:](chapters/ch01.0-what-is-a-web-server-anyway.md#parts-of-a-web-server-)
- [Navigating the World of Protocols: A Quick Overview](chapters/ch01.0-what-is-a-web-server-anyway.md#navigating-the-world-of-protocols-a-quick-overview)
- [The Relationship Between HTTP and TCP: Ensuring Reliable Web Communication](chapters/ch01.0-what-is-a-web-server-anyway.md#the-relationship-between-http-and-tcp-ensuring-reliable-web-communication)
- [1. Data Integrity and Order](chapters/ch01.0-what-is-a-web-server-anyway.md#1-data-integrity-and-order)
- [2. Acknowledgment Mechanism](chapters/ch01.0-what-is-a-web-server-anyway.md#2-acknowledgment-mechanism)
- [3. Complex Interactions](chapters/ch01.0-what-is-a-web-server-anyway.md#3-complex-interactions)
- [4. Transmission Overhead](chapters/ch01.0-what-is-a-web-server-anyway.md#4-transmission-overhead)
- [Asking and Getting: How Web Servers Respond to Your Requests](chapters/ch01.0-what-is-a-web-server-anyway.md#asking-and-getting-how-web-servers-respond-to-your-requests)
- [The Request:](chapters/ch01.0-what-is-a-web-server-anyway.md#the-request-)
- [The Response:](chapters/ch01.0-what-is-a-web-server-anyway.md#the-response-)
- [Your first `node.js` program](chapters/ch02.0-your-first-nodejs-program.md#your-first-node-js-program)
- [What exactly is node or nodejs?](chapters/ch02.0-your-first-nodejs-program.md#what-exactly-is-node-or-nodejs-)
- [Your first node.js program](chapters/ch02.0-your-first-nodejs-program.md#your-first-node-js-program)
- [How does `console.log()` work in Node.js?](chapters/ch02.0-your-first-nodejs-program.md#how-does-console-log-work-in-node-js-)
- [The **`process` Object**:](chapters/ch02.0-your-first-nodejs-program.md#the-process-object-)
- [The `stdout` **property of the `process` object**:](chapters/ch02.0-your-first-nodejs-program.md#the-stdout-property-of-the-process-object-)
- [Working with files](chapters/ch03.0-working-with-files.md#working-with-files)
- [What will the logging library do](chapters/ch03.0-working-with-files.md#what-will-the-logging-library-do)
- [How do you work with files anyway?](chapters/ch03.0-working-with-files.md#how-do-you-work-with-files-anyway-)
- [Let’s get back to `files`](chapters/ch03.0-working-with-files.md#let-s-get-back-to-files-)
- [A little more about file descriptors](chapters/ch03.0-working-with-files.md#a-little-more-about-file-descriptors)
- [Creating our first file](chapters/ch03.0-working-with-files.md#creating-our-first-file)
- [`path` argument](chapters/ch03.0-working-with-files.md#-path-argument)
- [`flag` argument](chapters/ch03.0-working-with-files.md#-flag-argument)
- [`mode` argument](chapters/ch03.0-working-with-files.md#-mode-argument)
- [Reading from a file](chapters/ch03.0-working-with-files.md#reading-from-a-file)
- [A small primer on `for..of` and `for await..of` in javascript](chapters/ch03.0-working-with-files.md#a-small-primer-on-for-of-and-for-await-of-in-javascript)
- [`for..of`](chapters/ch03.0-working-with-files.md#-for-of-)
- [`for await..of`](chapters/ch03.0-working-with-files.md#-for-await-of-)
- [Reading the `json` file](chapters/ch03.0-working-with-files.md#reading-the-json-file)
- [Buffers](chapters/ch03.0-working-with-files.md#buffers)
- [Parsing the `json` file](chapters/ch03.0-working-with-files.md#parsing-the-json-file)
- [`logtar` our own logging library](chapters/ch04.0-logtar-our-logging-library.md#-logtar-our-own-logging-library)
- [Initializing a new project](chapters/ch04.0-logtar-our-logging-library.md#initializing-a-new-project)
- [A little about `SemVer`](chapters/ch04.0-logtar-our-logging-library.md#a-little-about-semver-)
- [Creating a `LogLevel` class](chapters/ch04.0-logtar-our-logging-library.md#creating-a-loglevel-class)
- [The `Logger` class](chapters/ch04.0-logtar-our-logging-library.md#the-logger-class)
- [Encapsulation with `private` fields](chapters/ch04.0-logtar-our-logging-library.md#encapsulation-with-private-fields)
- [The `LogConfig` class](chapters/ch04.0-logtar-our-logging-library.md#the-logconfig-class)
- [Design patterns](chapters/ch04.0-logtar-our-logging-library.md#design-patterns)
- [The `Builder` pattern](chapters/ch04.0-logtar-our-logging-library.md#the-builder-pattern)
- [Using `builder` pattern with the `LogConfig` class](chapters/ch04.0-logtar-our-logging-library.md#using-builder-pattern-with-the-logconfig-class)
- [jsdoc comments](chapters/ch04.0-logtar-our-logging-library.md#jsdoc-comments)
- [The `RollingConfig` class](chapters/ch04.0-logtar-our-logging-library.md#the-rollingconfig-class)
- [The `RollingSizeOptions` class](chapters/ch04.0-logtar-our-logging-library.md#the-rollingsizeoptions-class)
- [The `RollingTimeOptions` class](chapters/ch04.0-logtar-our-logging-library.md#the-rollingtimeoptions-class)
- [Finishing up the `RollingConfig` class](chapters/ch04.0-logtar-our-logging-library.md#finishing-up-the-rollingconfig-class)
- [Let's recap](chapters/ch04.0-logtar-our-logging-library.md#let-s-recap)
- [Adding more useful methods in the `LogConfig` class](chapters/ch04.0-logtar-our-logging-library.md#adding-more-useful-methods-in-the-logconfig-class)
- [Why `readFileSync`?](chapters/ch04.0-logtar-our-logging-library.md#why-readfilesync-)
- [Refactoring the code](chapters/ch04.1-refactoring-the-code.md#refactoring-the-code)
- [**The Need for Refactoring**](chapters/ch04.1-refactoring-the-code.md#-the-need-for-refactoring-)
- [**Creating Separate Files**](chapters/ch04.1-refactoring-the-code.md#-creating-separate-files-)
- [The `index.js` file](chapters/ch04.1-refactoring-the-code.md#the-index-js-file)
- [The `lib/logtar.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-logtar-js-file)
- [The `lib/logger.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-logger-js-file)
- [The `lib/config/log-config.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-config-log-config-js-file)
- [The `lib/config/rolling-config.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-config-rolling-config-js-file)
- [The `lib/utils/log-level.js` file](chapters/ch04.1-refactoring-the-code.md#the-lib-utils-log-level-js-file)
- [The `lib/utils/rolling-options.js` class](chapters/ch04.1-refactoring-the-code.md#the-lib-utils-rolling-options-js-class)
- [Writing logs](chapters/ch04.2-writing-logs.md#writing-logs)
- [1. Re-using the File Handle](chapters/ch04.2-writing-logs.md#1-re-using-the-file-handle)
- [2. Log Rotation](chapters/ch04.2-writing-logs.md#2-log-rotation)
- [3. Asynchronous Logging](chapters/ch04.2-writing-logs.md#3-asynchronous-logging)
- [4. Getting Caller Information (Module and Line Number)](chapters/ch04.2-writing-logs.md#4-getting-caller-information-module-and-line-number-)
- [Testing our current API](chapters/ch04.2-writing-logs.md#testing-our-current-api)
- [Implementing logging methods](chapters/ch04.2-writing-logs.md#implementing-logging-methods)
- [DRY (Don't Repeat Yourself)](chapters/ch04.2-writing-logs.md#dry-don-t-repeat-yourself-)
- [The `log` method](chapters/ch04.2-writing-logs.md#the-log-method)
- [Considering the `log_level` member variable](chapters/ch04.2-writing-logs.md#considering-the-log_level-member-variable)
- [Writing to a file](chapters/ch04.2-writing-logs.md#writing-to-a-file)
- [Another gotcha](chapters/ch04.2-writing-logs.md#another-gotcha)
- [Logs directory configuration](chapters/ch04.2-writing-logs.md#logs-directory-configuration)
- [The `require` object](chapters/ch04.2-writing-logs.md#the-require-object)
- [Adding a new helper to create log directory](chapters/ch04.2-writing-logs.md#adding-a-new-helper-to-create-log-directory)
- [Updating the `init` method](chapters/ch04.2-writing-logs.md#updating-the-init-method)
- [Completing the `log` method](chapters/ch04.2-writing-logs.md#completing-the-log-method)
- [Capturing metadata](chapters/ch04.3-capturing-metadata.md#capturing-metadata)
- [What is a Stack?](chapters/ch04.3-capturing-metadata.md#what-is-a-stack-)
- [Examples of Stacks](chapters/ch04.3-capturing-metadata.md#examples-of-stacks)
- [The Call Stack](chapters/ch04.3-capturing-metadata.md#the-call-stack)
- [Getting the stack info](chapters/ch04.3-capturing-metadata.md#getting-the-stack-info)
- [Getting the `callee` name and the line number](chapters/ch04.3-capturing-metadata.md#getting-the-callee-name-and-the-line-number)
- [A more ergonomic way](chapters/ch04.3-capturing-metadata.md#a-more-ergonomic-way)
- [Using the `get_caller_info` function](chapters/ch04.3-capturing-metadata.md#using-the-get_caller_info-function)
- [A small intro to `async` vs `sync`](chapters/ch04.4-intro-to-async-vs-sync.md#a-small-intro-to-async-vs-sync-)
- [The Balance between Opposites](chapters/ch04.4-intro-to-async-vs-sync.md#the-balance-between-opposites)
- [Mixing Asynchronous and Synchronous Code](chapters/ch04.4-intro-to-async-vs-sync.md#mixing-asynchronous-and-synchronous-code)
- [Faster I/O out of the box](chapters/ch04.4-intro-to-async-vs-sync.md#faster-i-o-out-of-the-box)
- [Blocking Code](chapters/ch04.4-intro-to-async-vs-sync.md#blocking-code)
- [Concurrency](chapters/ch04.4-intro-to-async-vs-sync.md#concurrency)
- [Adding Rolling File Support](chapters/ch04.5-rolling-file-support.md#adding-rolling-file-support)
- [Rolling features](chapters/ch04.5-rolling-file-support.md#rolling-features)
- [The `rolling_check()` method](chapters/ch04.5-rolling-file-support.md#the-rolling_check-method)
- [`file_handle.stat()`](chapters/ch04.5-rolling-file-support.md#-file_handle-stat-)
- [Calling the `rolling_check` method](chapters/ch04.5-rolling-file-support.md#calling-the-rolling_check-method)
- [A big gotcha!](chapters/ch04.5-rolling-file-support.md#a-big-gotcha-)
- [Stack traces across `await` points](chapters/ch04.5-rolling-file-support.md#stack-traces-across-await-points)
- [Testing the new Log file creation](chapters/ch04.5-rolling-file-support.md#testing-the-new-log-file-creation)
- [HTTP Deep dive](chapters/ch05.0-http-deep-dive.md#http-deep-dive)
- [A small web server](chapters/ch05.0-http-deep-dive.md#a-small-web-server)
- [Starting our web server](chapters/ch05.0-http-deep-dive.md#starting-our-web-server)
- [Testing our web server](chapters/ch05.0-http-deep-dive.md#testing-our-web-server)
- [Testing with `cURL`](chapters/ch05.0-http-deep-dive.md#testing-with-curl-)
- [HTTP Verbs, Versioning and the benefits of `HTTP/1.1`](chapters/ch05.1-http-verbs-versioning-http1_1.md#http-verbs-versioning-and-the-benefits-of-http-1-1-)
- [`GET` - Retrieve data](chapters/ch05.1-http-verbs-versioning-http1_1.md#-get-retrieve-data)
- [`POST` - Create something](chapters/ch05.1-http-verbs-versioning-http1_1.md#-post-create-something)
- [`PUT` - Replace or Create](chapters/ch05.1-http-verbs-versioning-http1_1.md#-put-replace-or-create)
- [`HEAD` - Retrieve Metadata](chapters/ch05.1-http-verbs-versioning-http1_1.md#-head-retrieve-metadata)
- [`DELETE` - Remove from existence](chapters/ch05.1-http-verbs-versioning-http1_1.md#-delete-remove-from-existence)
- [`PATCH` - Partial updates](chapters/ch05.1-http-verbs-versioning-http1_1.md#-patch-partial-updates)
- [A small recap](chapters/ch05.1-http-verbs-versioning-http1_1.md#a-small-recap)
- [The `/` path](chapters/ch05.1-http-verbs-versioning-http1_1.md#the-path)
- [`HTTP/0.9`](chapters/ch05.1-http-verbs-versioning-http1_1.md#-http-0-9-)
- [`HTTP/1.0`](chapters/ch05.1-http-verbs-versioning-http1_1.md#-http-1-0-)
- [`HTTP/1.1`](chapters/ch05.1-http-verbs-versioning-http1_1.md#-http-1-1-)
- [User agents](chapters/ch05.2-user-agents.md#user-agents)
- [`User-Agent` can be weird](chapters/ch05.2-user-agents.md#-user-agent-can-be-weird)
- [MIME Type and `Content-Type`](chapters/ch05.3-mime-type-and-content-type.md#mime-type-and-content-type-)
- [Understanding the `Accept` Header](chapters/ch05.3-mime-type-and-content-type.md#understanding-the-accept-header)
- [Mime Type](chapters/ch05.3-mime-type-and-content-type.md#mime-type)
- [Anatomy of a MIME type](chapters/ch05.3-mime-type-and-content-type.md#anatomy-of-a-mime-type)
- [But why the wildcard `*/*`?](chapters/ch05.3-mime-type-and-content-type.md#but-why-the-wildcard-)
- [The `Content-Type` header](chapters/ch05.3-mime-type-and-content-type.md#the-content-type-header)
- [The `charset=UTF-8`: character encoding](chapters/ch05.3-mime-type-and-content-type.md#the-charset-utf-8-character-encoding)
- [Headers](chapters/ch05.4-headers.md#headers)
- [Header Name](chapters/ch05.4-headers.md#header-name)
- [Colon (`:`)](chapters/ch05.4-headers.md#colon-)
- [Header Value](chapters/ch05.4-headers.md#header-value)
- [Whitespace](chapters/ch05.4-headers.md#whitespace)
- [Custom `X-` based headers](chapters/ch05.4-headers.md#custom-x-based-headers)
- [Request headers](chapters/ch05.4-headers.md#request-headers)
- [Accept](chapters/ch05.4-headers.md#accept)
- [Referer](chapters/ch05.4-headers.md#referer)
- [Authorization](chapters/ch05.4-headers.md#authorization)
- [Cookie](chapters/ch05.4-headers.md#cookie)
- [Host](chapters/ch05.4-headers.md#host)
- [Content-Type (request)](chapters/ch05.4-headers.md#content-type-request-)
- [Response Headers](chapters/ch05.4-headers.md#response-headers)
- [Content-Type (response)](chapters/ch05.4-headers.md#content-type-response-)
- [Cache-Control](chapters/ch05.4-headers.md#cache-control)
- [Set-Cookie](chapters/ch05.4-headers.md#set-cookie)
- [Response and Status Codes](chapters/ch05.5-response-status-codes.md#response-and-status-codes)
- [`Connection: close` in action](chapters/ch05.5-response-status-codes.md#-connection-close-in-action)
- [Status Codes](chapters/ch05.5-response-status-codes.md#status-codes)
- [`Velocy` - Our backend framework](chapters/ch06.00-velocy-our-backend-framework.md#-velocy-our-backend-framework)
- [Why Velocy?](chapters/ch06.00-velocy-our-backend-framework.md#why-velocy-)
- [What is a backend framework/library anyway?](chapters/ch06.00-velocy-our-backend-framework.md#what-is-a-backend-framework-library-anyway-)
- [Core features of our backend framework](chapters/ch06.00-velocy-our-backend-framework.md#core-features-of-our-backend-framework)
- [Routing and URL Handling:](chapters/ch06.00-velocy-our-backend-framework.md#routing-and-url-handling-)
- [Middlewares](chapters/ch06.00-velocy-our-backend-framework.md#middlewares)
- [Building our own database](chapters/ch06.00-velocy-our-backend-framework.md#building-our-own-database)
- [Caching](chapters/ch06.00-velocy-our-backend-framework.md#caching)
- [Rate limiting](chapters/ch06.00-velocy-our-backend-framework.md#rate-limiting)
- [Some other features that we will be implementing](chapters/ch06.00-velocy-our-backend-framework.md#some-other-features-that-we-will-be-implementing)
- [A basic `Router` implementation](chapters/ch06.01-basic-router-implementation.md#a-basic-router-implementation)
- [A Toy Router](chapters/ch06.01-basic-router-implementation.md#a-toy-router)
- [`Transfer-Encoding: chunked`](chapters/ch06.01-basic-router-implementation.md#-transfer-encoding-chunked-)
- [Chunks, oh no!](chapters/ch06.01-basic-router-implementation.md#chunks-oh-no-)
- [Specifying `Content-Length`](chapters/ch06.01-basic-router-implementation.md#specifying-content-length-)
- [Code reusability](chapters/ch06.01-basic-router-implementation.md#code-reusability)
- [The `Router` class](chapters/ch06.02-the-router-class.md#the-router-class)
- [Using `Router` with an HTTP server](chapters/ch06.02-the-router-class.md#using-router-with-an-http-server)
- [`this` is not good](chapters/ch06.02-the-router-class.md#-this-is-not-good)
- [Lexical Context](chapters/ch06.02-the-router-class.md#lexical-context)
- [Arrow functions are not free](chapters/ch06.02-the-router-class.md#arrow-functions-are-not-free)
- [Why should we care about memory?](chapters/ch06.02-the-router-class.md#why-should-we-care-about-memory-)
- [Testing the updated code](chapters/ch06.02-the-router-class.md#testing-the-updated-code)
- [Improving the `Router` API](chapters/ch06.03-improving-the-router-api.md#improving-the-router-api)
- [The Need for a `Trie`](chapters/ch06.04-the-need-for-a-trie.md#the-need-for-a-trie-)
- [What is a `Trie` anyway?](chapters/ch06.04-the-need-for-a-trie.md#what-is-a-trie-anyway-)
- [Ex. Implementing a `Trie`](chapters/ch06.05-ex-implementing-a-trie.md#ex-implementing-a-trie-)
- [Root Node](chapters/ch06.05-ex-implementing-a-trie.md#root-node)
- [End of the word](chapters/ch06.05-ex-implementing-a-trie.md#end-of-the-word)
- [Challenge 1: Basic Trie with `insert` Method](chapters/ch06.05-ex-implementing-a-trie.md#challenge-1-basic-trie-with-insert-method)
- [Challenge 2: Implement `search` method](chapters/ch06.05-ex-implementing-a-trie.md#challenge-2-implement-search-method)
- [Ex. Implementing our Trie based `Router`](chapters/ch06.06-ex-implementing-router.md#ex-implementing-our-trie-based-router-)
- [Challenge 1: Implementing the `addRoute` method](chapters/ch06.06-ex-implementing-router.md#challenge-1-implementing-the-addroute-method)
- [Challenge 2: Implementing the `findRoute` method](chapters/ch06.06-ex-implementing-router.md#challenge-2-implementing-the-findroute-method)
- [Ex. Adding `HTTP` method support](chapters/ch06.07-ex-adding-http-methods.md#ex-adding-http-method-support)
- [Requirements](chapters/ch06.07-ex-adding-http-methods.md#requirements)
- [More details](chapters/ch06.07-ex-adding-http-methods.md#more-details)
- [Example](chapters/ch06.07-ex-adding-http-methods.md#example)
- [Hints](chapters/ch06.07-ex-adding-http-methods.md#hints)
- [Solution](chapters/ch06.07-ex-adding-http-methods.md#solution)
- [Adding HTTP methods to the Router](chapters/ch06.08-adding-verbs-api.md#adding-http-methods-to-the-router)
- [Update the `TrieRouter` class](chapters/ch06.08-adding-verbs-api.md#update-the-trierouter-class)
- [Ex. Implementing Dynamic Routing](chapters/ch06.09-ex-dynamic-routing.md#ex-implementing-dynamic-routing)
- [Why Dynamic Routing?](chapters/ch06.09-ex-dynamic-routing.md#why-dynamic-routing-)
- [Anatomy of a dynamic route](chapters/ch06.09-ex-dynamic-routing.md#anatomy-of-a-dynamic-route)
- [Challenge: Enhance the `TrieRouter` Class to Support Dynamic Routing](chapters/ch06.09-ex-dynamic-routing.md#challenge-enhance-the-trierouter-class-to-support-dynamic-routing)
- [Visualisation of our `TrieRouter` structure](chapters/ch06.09-ex-dynamic-routing.md#visualisation-of-our-trierouter-structure)
- [Summary](chapters/ch06.09-ex-dynamic-routing.md#summary)
- [Running Our Server](chapters/ch06.10-running-our-server.md#running-our-server)
- [Refactoring the `TrieRouter` class](chapters/ch06.10-running-our-server.md#refactoring-the-trierouter-class)
- [Type Aliases](chapters/ch06.10-running-our-server.md#type-aliases)
- [The `run` function](chapters/ch06.10-running-our-server.md#the-run-function)
- [Building our first web-server](chapters/ch06.11-building-a-web-server.md#building-our-first-web-server)
- [More refactoring](chapters/ch06.11-building-a-web-server.md#more-refactoring)
- [Your first web server](chapters/ch06.11-building-a-web-server.md#your-first-web-server)
- [Ex. Query Parameters (Advanced)](chapters/ch06.12-query-parameters.md#ex-query-parameters-advanced-)
- [Anatomy of a URL with Query Parameters](chapters/ch06.12-query-parameters.md#anatomy-of-a-url-with-query-parameters)
- [Challenge 1: Implementing Basic Query Parameter Parsing](chapters/ch06.12-query-parameters.md#challenge-1-implementing-basic-query-parameter-parsing)
- [We need to tackle more edge cases](chapters/ch06.12-query-parameters.md#we-need-to-tackle-more-edge-cases)
- [Challenge 2: Parsing Query Parameters Manually](chapters/ch06.12-query-parameters.md#challenge-2-parsing-query-parameters-manually)