Course Highlights
  • Architect large, scalable apps using a collection of microservices
  • Deploy a multi-service app to the cloud with Docker and Kubernetes
  • Solve concurrency issues in a distributed systems environment
  • Leverage your Javascript skills to build a complex web app
  • Build a Server-Side Rendered React App to render data from your microservices
  • Understand how enterprise companies design their infrastructure
  • Share reusable code between multiple Express servers using custom NPM packages
  • Write comprehensive tests to ensure each service works as designed
  • Communicate data between services using a lightning-fast event bus
  • Write nothing but production-level code. No cutting corners!
Curriculum

10 Topics
How to Get Help
Course Resources
What Is a Microservice?
Data in Microservices
Quiz - Data in Microservices
Big Problems with Data
Sync Communication Between Services
Event-Based Communication
A Crazy Way of Storing Data
Pros and Cons of Async Communication

43 Topics
Important - Optional Boilerplate
App Overview
Project Setup
Posts Service Creation
Testing the Posts Service
Implementing a Comments Service
Quick Comments Test
Note on the React App
Addressing Default Export and ReactDom.render Warnings
React Project Setup
Building Post Submission
Handling CORS Errors
Fetching and Rendering Posts
Creating Comments
Displaying Comments
Completed React App
Request Minimization Strategies
An Async Solution
Common Questions Around Async Events
Event Bus Overview
Important Note about Node v15 and Unhandled Promise Rejections
A Basic Event Bus Implementation
Emitting Events
Emitting Comment Creation Events
Receiving Events
Creating the Data Query Service
Parsing Incoming Events
Using the Query Service
Adding a Simple Feature
Issues with Comment Filtering
A Second Approach
How to Handle Resource Updates
Creating the Moderation Service
Adding Comment Moderation
Reminder about Node v15 and Error Catching
Handling Moderation
Updating Comment Content
A Quick Test
Rendering Comments by Status
Dealing with Missing Events
Required Node v15+ Update for Query Service
Implementing Event Sync
Event Syncing in Action

8 Topics
Deployment Issues
Why Docker?
Why Kubernetes?
Don't Know Docker? Watch This.
Note About Docker Build Output and Buildkit
Dockerizing the Posts Service
Review Some Basic Commands
Dockering Other Services

44 Topics
Warning on Docker Desktop for Linux
Installing Kubernetes
IMPORTANT Note for Minikube and MicroK8s Users
A Kubernetes Tour
Important Kubernetes Terminology
Notes on Config Files
Creating a Pod
ErrImagePull ErrImageNeverPull and ImagePullBackoff Errors
Understanding a Pod Spec
Common Kubectl Commands
A Time-Saving Alias
Introducing Deployments
Creating a Deployment
Common Commands Around Deployments
Updating Deployments
Preferred Method for Updating Deployments
Networking With Services
Creating a NodePort Service
Accessing NodePort Services
Setting Up Cluster IP Services
Building a Deployment for the Event Bus
Adding ClusterIP Services
How to Communicate Between Services
Updating Service Addresses
Verifying Communication
Adding Query Moderation and Comments
Testing Communication
Load Balancer Services
Load Balancers and Ingress
Important - DO NOT SKIP - Ingress Nginx Installation Info
Installing Ingress-Nginx
Ingress v1 API Required Update + pathType Warning
Writing Ingress Config Files
Important Note About Port 80
Hosts File Tweak
Important Note to Add Environment Variable
Deploying the React App
Unique Route Paths
Final Route Config
Introducing Skaffold
Skaffold Setup
Skaffold API version Update
First Time Skaffold Startup
A Few Notes on Skaffold

13 Topics
Big Ticket Items
App Overview
Resource Types
Service Types
Events and Architecture Design
Note on Typescript
Auth Service Setup
Auth K8s Setup
Adding Skaffold
Note on Code Reloading
Ingress v1 API Required Update
Ingress-Nginx Setup
Hosts File and Security Warning

12 Topics
Note on Remote Development
Remote Dev with Skaffold
Free Google Cloud Credits
Google Cloud Initial Setup
Kubernetes Cluster Creation
Kubectl Contexts
Initializing the GCloud SDK
Installing the GCloud Context
Updating the Skaffold Config
More Skaffold Updates
Creating a Load Balancer
Final Config and Test

21 Topics
Creating Route Handlers
Scaffolding Routes
Adding Validation
Handling Validation Errors
Postman HTTPS Issues
Surprising Complexity Around Errors
Other Sources of Errors
Solution for Error Handling
Building an Error Handling Middleware
Communicating More Info to the Error Handler
Encoding More Information In an Error
Subclassing for Custom Errors
Determining Error Type
Property 'param' does not exist on type 'AlternativeValidationError'
Converting Errors to Responses
Moving Logic Into Errors
serializeErrors' not assignable to the same property in base type 'CustomError'
Verifying Our Custom Errors
Final Error Related Code
How to Define New Custom Errors
Uh Oh... Async Error Handling

16 Topics
Creating Databases in Kubernetes
Connecting to MongoDB
Understanding the Signup Flow
Getting TypeScript and Mongoose to Cooperate
Creating the User Model
Type Checking User Properties
Adding Static Properties to a Model
Defining Extra Document Properties
What's That Angle Bracket For?
User Creation
Proper Error Handling
Note on Password Hashing
Reminder on Password Hashing
Adding Password Hashing
Comparing Hashed Password
Mongoose Pre-Save Hooks

26 Topics
Fundamental Authentication Strategies
Huge Issues with Authentication Strategies
So Which Option?
Solving Issues with Option #2
Reminder on Cookies vs JWT's
Microservices Auth Requirements
Issues with JWT's and Server Side Rendering
Cookies and Encryption
Adding Session Support
Generating a JWT
JWT Signing Keys
Securely Storing Secrets with Kubernetes
Creating and Accessing Secrets
Accessing Env Variables in a Pod
Common Response Properties
Formatting JSON Properties
The Signin Flow
Common Request Validation Middleware
Sign In Logic
Quick Sign In Test
Current User Handler
Returning the Current User
Signing Out
Creating a Current User Middleware
Augmenting Type Definitions
Requiring Auth for Route Access

20 Topics
Scope of Testing
Testing Goals
Testing Architecture
Index to App Refactor
Replacing --only=prod Install Flag
A Few Dependencies
Required MongoMemoryServer Updates
Test Environment Setup
Our First Test
An Important Note
Testing Invalid Input
Requiring Unique Emails
Changing Node Env During Tests
Tests Around Sign In Functionality
Testing Sign Out
Issues with Cookies During Testing
Easy Auth Solution
globalThis has no index signature TS Error
Auth Helper Function
Testing Non-Authed Requests

40 Topics
Starting the React App
Reminder on Server Side Rendering
Suggestion Regarding a Default Export Warning
Basics of Next JS
Building a Next Image
Running Next in Kubernetes
Small Update for Custom Webpack Config
Note on File Change Detection
Adding Global CSS
Adding a Sign Up Form
Handling Email and Password Inputs
Successful Account Signup
Handling Validation Errors
The useRequest Hook
Using the useRequest Hook
An onSuccess Callback
Overview on Server Side Rendering
A note about ECONNREFUSED errors
Fetching Data During SSR
Why the Error?
Two Possible Solutions
Cross Namespace Service Communication
When is GetInitialProps Called?
On the Server or the Browser
Ingress-Nginx Namespace and Service - Important Update
Specifying the Host
Passing Through the Cookies
A Reusable API Client
Content on the Landing Page
The Sign In Form
A Reusable Header
Moving GetInitialProps
Issues with Custom App GetInitialProps
Handling Multiple GetInitialProps
Passing Props Through
Error: Invalid <Link> with <a> child
Building the Header
Conditionally Showing Links
Signing Out
React App Catchup & Checkpoint

10 Topics
Shared Logic Between Services
Options for Code Sharing
NPM Organizations
Publishing NPM Modules
Project Setup
Typo in package.json "files" Field - Do Not Skip
An Easy Publish Command
Relocating Shared Code
Updating Import Statements
Updating the Common Module

26 Topics
Ticketing Service Overview
Project Setup
Running the Ticket Service
Mongo Connection URI
Quick Auth Update
Test-First Approach
Creating the Router
Adding Auth Protection
Faking Authentication During Tests
A Required Session Fix and a Global Signin Reminder
Building a Session
Testing Request Validation
Validating Title and Price
Reminder on Mongoose with TypeScript
Defining the Ticket Model
Creation via Route Handler
Testing Show Routes
Unexpected Failure!
What's that Error?!
Better Error Logging
Complete Index Route Implementation
Ticket Updating
Handling Updates
Permission Checking
Final Update Changes
Manual Testing

23 Topics
What Now?
NATS Server Status - IMPORTANT NOTE
Three Important Items
Creating a NATS Streaming Deployment
Big Notes on NATS Streaming
Building a NATS Test Project
Port-Forwarding with Kubectl
Publishing Events
Small Required Command Change
Listening For Data
Accessing Event Data
Client ID Generation
Queue Groups
Manual Ack Mode
Client Health Checks
Graceful Client Shutdown
Core Concurrency Issues
Common Questions
[Optional] More Possible Concurrency Solutions
Solving Concurrency Issues
Concurrency Control with the Tickets App
Event Redelivery
Durable Subscriptions

17 Topics
Reusable NATS Listeners
The Listener Abstract Class
Extending the Listener
Quick Refactor
Leveraging TypeScript for Listener Validation
Subjects Enum
Custom Event Interface
Enforcing Listener Subjects
Quick Note: 'readonly' in Typescript
Enforcing Data Types
Where Does this Get Used?
Custom Publisher
Using the Custom Publisher
Awaiting Event Publication
Common Event Definitions Summary
Updating the Common Module
Restarting NATS

19 Topics
Publishing Ticket Creation
More on Publishing
NATS Client Singleton
Node Nats Streaming Installation
Remember Mongoose?
TS Error - Did you forget to include 'void' in your type argument
Singleton Implementation
Accessing the NATS Client
Graceful Shutdown
Successful Listen!
Ticket Update Publishing
Failed Event Publishing
Handling Publish Failures
Fixing a Few Tests
Redirecting Imports
Providing a Mock Implementation
Test-Suite Wide Mocks
Ensuring Mock Invocations
NATS Env Variables

28 Topics
The Orders Service
Scaffolding the Orders Service
A Touch More Setup
Ingress Routing Rules
Scaffolding a Few Route Handlers
Subtle Service Coupling
Associating Orders and Tickets
Order Model Setup
The Need for an Enum
Creating an Order Status Enum
More on Mongoose Refs
Defining the Ticket Model
Order Creation Logic
Finding Reserved Tickets
Convenience Document Methods
Order Expiration Times
globalThis has no index signature TS Error
Test Suite Setup
Small Update for "Value of type 'typeof ObjectId' is not callable"
Asserting Tickets Exist
Asserting Reserved Tickets
Testing the Success Case
Fetching a User's Orders
A Slightly Complicated Test
Fetching Individual Orders
Does Fetching Work?
Cancelling an Order
Can We Cancel?

6 Topics
Orders Service Events
Creating the Events
Implementing the Publishers
Publishing the Order Creation
Publishing Order Cancellation
Testing Event Publishing

48 Topics
Heads Up Regarding Some Mongoose TS Errors
Time for Listeners!
Reminder on Listeners
Blueprint for Listeners
A Few More Reminders
Simple onMessage Implementation
ID Adjustment
Ticket Updated Listener Implementation
Initializing the Listeners
A Quick Manual Test
Clear Concurrency Issues
Reminder on Versioning Records
Optimistic Concurrency Control
Mongoose Update-If-Current
Implementing OCC with Mongoose
Test functions cannot both take a 'done' callback and return something Error
Testing OCC
One More Test
Who Updates Versions?
Including Versions in Events
Updating Tickets Event Definitions
Property 'version' is missing TS Errors After Running Skaffold
Applying a Version Query
Did it Work?
Abstracted Query Method
[Optional] Versioning Without Update-If-Current
Testing Listeners
A Complete Listener Test
Testing the Ack Call
Testing the Ticket Updated Listener
Success Case Testing
Out-Of-Order Events
The Next Few Videos
Fixing a Few Tests
Listeners in the Tickets Service
Building the Listener
Strategies for Locking a Ticket
Reserving a Ticket
Setup for Testing Reservation
Test Implementation
Missing Update Event
Private vs Protected Properties
Publishing While Listening
Mock Function Arguments
Order Cancelled Listener
A Lightning-Quick Test
Don't Forget to Listen!
Rejecting Edits of Reserved Tickets

19 Topics
The Expiration Service
Expiration Options
Initial Setup
Skaffold errors - Expiration Image Can't be Pulled
A Touch of Kubernetes Setup
File Sync Setup
Listener Creation
What's Bull All About?
Creating a Queue
Queueing a Job on Event Arrival
Testing Job Processing
Delaying Job Processing
Defining the Expiration Complete Event
Publishing an Event on Job Processing
Handling an Expiration Event
Emitting the Order Cancelled Event
Testing the Expiration Complete Listener
A Touch More Testing
Listening for Expiration

31 Topics
The Payments Service
globalThis has no index signature TS Error
Initial Setup
Replicated Fields
Another Order Model!
Update-If-Current
Replicating Orders
Testing Order Creation
Marking an Order as Cancelled
Cancelled Testing
Starting the Listeners
Payments Flow with Stripe
Implementing the Create Charge Handler
Validating Order Payment
Testing Order Validation Before Payment
Testing Same-User Validation
Stripe Setup
Creating a Stripe Secret
Creating a Charge with Stripe
Manual Testing of Payments
Automated Payment Testing
Mocked Stripe Client
A More Realistic Test Setup
Realistic Test Implementation
Tying an Order and Charge Together
Testing Payment Creation
Publishing a Payment Created Event
More on Publishing
Marking an Order as Complete
Important Info About the Next Lecture - Don't Skip
Don't Cancel Completed Orders!

21 Topics
A Few More Pages
Reminder on Data Fetching with Next
Two Quick Fixes
Scaffolding a Form
Sanitizing Price Input
Ticket Creation
Listing All Tickets
Reminder on Invalid <Link> with <a> child Errors
Linking to Wildcard Routes
Creating an Order
Programmatic Navigation to Wildcard Routes
The Expiration Timer
Displaying the Expiration
Showing a Stripe Payment Form
Module not found: Can't resolve 'prop-types'
Configuring Stripe
Test Credit Card Numbers
Paying for an Order
Filtering Reserved Tickets
Header Links
Rendering a List of Orders

30 Topics
Development Workflow
Git Repository Approaches
Creating a GitHub Action
Adding a CI Test Script
Tests in GitHub Actions Hang - Jest did not exit
Running Tests on PR Creation
Output of Failing Tests
Running Tests in Parallel
Verifying a Test Run
Selective Test Execution
Deployment Options
Creating a Hosted Cluster
Reminder on Kubernetes Context
Reminder on Swapping Contexts
The Deployment Plan
Building an Image in an Action
Testing the Image Build
Restarting the Deployment
Applying Kubernetes Manifests
Prod vs Dev Manifest Files
Manual Secret Creation
Don't Forget Ingress-Nginx!
Testing Automated Deployment
Additional Deploy Files
A Successful Deploy!
Buying a Domain Name
Three Important Changes Needed to Deploy - Do Not Skip!
Configuring the Domain Name
I Really Hope This Works
Next Steps

46 Topics
Finished Code and Diagrams
Why Use Docker?
What is Docker?
Docker for Mac / Windows
Installing Docker on macOS
Installing Docker with WSL2 on Windows 10/11
Installing Docker on Linux
Using the Docker Client
But Really... What's a Container?
How's Docker Running on Your Computer?
Docker Run in Detail
Overriding Default Commands
Listing Running Containers
Container Lifecycle
Restarting Stopped Containers
Removing Stopped Containers
Retrieving Output Logs
Stopping Containers
Multi-Command Containers
Executing Commands in Running Containers
The Purpose of the 'it' Flag
Getting a Command Prompt in a Container
Starting with a Shell
Container Isolation
Creating Docker Images
Buildkit for Docker Desktop
Building a Dockerfile
Dockerfile Teardown
What's a Base Image?
The Build Process in Detail
A Brief Recap
Rebuilds with Cache
Tagging an Image
Quick Note for Windows Users
Manual Image Generation with Docker Commit
Project Outline
Node Server Setup
A Few Planned Errors
Required Node Base Image Version
Base Image Issues
A Few Missing Files
Copying Build Files
Container Port Forwarding
Specifying a Working Directory
Unnecessary Rebuilds
Minimizing Cache Busting and Rebuilds

75 Topics
How to Get Help
TypeScript Overview
Environment Setup
Important Axios Version Information
A First App
Executing Typescript Code
One Quick Change
Catching Errors with TypeScript
Catching More Errors!
Do Not Skip - Course Overview
Types
More on Types
Examples of Types
Where Do We Use Types?
Type Annotations and Inference
Annotations With Variables
Object Literal Annotations
Annotations Around Functions
Understanding Inference
The Any Type
Fixing the "Any" Type
Delayed Initialization
When Inference Doesn't Work
More on Annotations Around Functions
Inference Around Functions
Annotations for Anonymous Functions
Void and Never
Destructuring with Annotations
Annotations Around Objects
Arrays in TypeScript
Why Typed Arrays?
Multiple Typees in Arrays
When to Use Typed Arrays
Tuples in TypeScript
Tuples in Action
Why Tuples?
Interfaces
Long Type Annotations
Fixing Annotations With Interfaces
Syntax Around Interfaces
Functions in Interfaces
Code Reuse with Interfaces
General Plan with Interfaces
Classes
Basic Inheritance
Class Method Modifiers
Fields in Classes
Fields with Inheritance
Where to Use Classes
Updated Parcel Instructions
App Overview
Bundling with Parcel
Project Structure
IMPORTANT Info About Faker Installation
Generating Random Data
Type Definition Files
Using Type Definition Files
Export Statements in TypeScript
Defining a Company
Important Note About Google Maps Key
Adding Google Maps Support
Required Update for New @types Library
Google Maps Integration with TypeScript
Exploring Type Definition Files
Hiding Functionality
Why Use Private Modifiers? Here's Why
Adding Markers
Duplicate Code
One Possible Solution
Restricting Access with Interfaces
Implicit Type Checks
Showing Popup Windows
Updating Interface Definitions
Optional Implements Clauses
App Wrapup

1 Topic
Bonus!

  Write a Review

Microservices with Node JS and React

Go to Paid Course