Microservices with Node JS and React
Build, deploy, and scale an E-Commerce app using Microservices built with Node, React, Docker and Kubernetes
Build, deploy, and scale an E-Commerce app using Microservices built with Node, React, Docker and Kubernetes
Event-Based Architecture? Covered! Server side rendering with React? Yep. Scalable, production-ready code? Its here!
This course requires you to download Docker Desktop from Docker. If you are a Udemy Business user, please check with your employer before downloading software.
Microservices are the number one solution for building and scaling out apps that are intended to grow. Just one little issue: there are few resources online that delve into the most complex and nasty issues around them! I built this course to fix that. This course tackles every major issues around microservices head on. From challenges with data replication to confusing unordered event streams, every major challenge of building microservices is covered.
Beyond focusing on the basics of microservices, this course is a perfect introduction to the world of full-stack development. You will work all the way from the frontend, assembling a React app using Hooks, to the backend, including database design and deployment strategies. Every step along the way is covered in tremendous detail, with ample diagrams to ensure every step is crystal clear.
Many other resources show only the easiest, simplest apps written with microservices. This course does the opposite: we focus on the most challenging aspects of microservices, challenges that you will likely encounter every single day. You will see these difficulties first hand, then solve them with easy-to-understand strategies.
How This Course Works
This course doesn't focus on using an off-the-shelf microservices framework. Many exist, but they hide the inner workings and challenges of microservices away from you. Instead, we will be using a minimal number of libraries, and write as much custom code as possible. This will expose you to challenging problems and clever solutions when handling subjects like async events!
What Technology You'll Use
Because we are building a full stack application, we will use a variety of technologies. On the frontend, we'll use React and Next JS to present content to users. Each service is created using Node and Express. Data for each service is held in either a Mongo database or Redis. The entire app is deployed and runs in Docker containers executed in a Kubernetes cluster. Finally, almost all of the code in this course is written with Typescript.
This is a scary list of technologies! Not familiar with some of these? No problem! The course is built assuming that you only know the basics of Javascript and Express. No other knowledge is needed - you will learn everything you need to know.
What You'll Be Able to Do
By the time you complete this course, you will be able to:
Architect a multi-service application
Determine whether your app is a good fit for a microservices approach
Understand and solve the challenges in async, event-based communication between services
Use Docker and Kubernetes to deploy a multi-service app to any cloud provider
Organize and enhance the reusability of code in large projects
What You'll Learn
An absolute incredible number of topics are covered in this course. Here is a partial list of what you'll do:
Practice patterns to create scalable microservices for a variety of app domains
Build a Server-Side-Rendered React app using Hooks and Next JS
Write a custom implementation of an event bus
Optionally, run a development environment through a cloud provider
Guarantee consistently structured responses from your different API's
See best practices in communication between different services
Configure and scale your services using Kubernetes Deployments
Document and enforce structure constraints on events shared across microservices
Limit access to your APIs using JWT-based authentication
And much more!
This is the course I wish I had when I was learning microservices. A course that focuses on the hardest parts, gives clear explanations, and discusses the pros and cons of different design options. Sign up today and join me in mastering microservices!
Khu vực Câu hỏi thường gặp trống
App Overview
Project Setup
Posts Service Creation
Testing the Posts Service
Implementing a Comments Service
Quick Comments Test
React Project Setup
Building Post Submission
Handling CORS Errors
Fetching and Rendering Posts
Creating Comments
Displaying Comments
Request Minimization Strategies
An Async Solution
Common Questions Around Async Events
Event Bus Overview
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
Handling Moderation
Updating Comment Content
A Quick Test
Rendering Comments by Status
Dealing with Missing Events
Implementing Event Sync
Event Syncing in Action
Important - Optional Boilerplate
Note on the React App
Addressing Default Export and ReactDom.render Warnings
Completed React App
Important Note about Node and Unhandled Promise Rejections
Reminder about Error Catching
Required Error Handling Update for Query Service
Installing Kubernetes
A Kubernetes Tour
Important Kubernetes Terminology
Notes on Config Files
Creating a Pod
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
Installing Ingress-Nginx
Writing Ingress Config Files
Hosts File Tweak
Deploying the React App
Unique Route Paths
Final Route Config
Introducing Skaffold
Skaffold Setup
First Time Skaffold Startup
A Few Notes on Skaffold
IMPORTANT Note for Minikube and MicroK8s Users
ErrImagePull, ErrImageNeverPull and ImagePullBackoff Errors
Important - DO NOT SKIP - Ingress Nginx Installation Info
Ingress v1 API Required Update + pathType Warning
Important Note About Port 80
Important Note to Add Environment Variable
Skaffold API version Update
Note on Remote Development
Remote Dev with Skaffold
Google Cloud Initial Setup
Kubectl Contexts
Installing the GCloud Context
Updating the Skaffold Config
More Skaffold Updates
Creating a Load Balancer
Final Config and Test
Free Google Cloud Trial and Credits
Kubernetes Cluster Creation with Autopilot
Initializing the GCloud SDK
Creating Route Handlers
Scaffolding Routes
Adding Validation
Handling Validation Errors
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
Converting Errors to Responses
Moving Logic Into Errors
Verifying Our Custom Errors
Final Error Related Code
How to Define New Custom Errors
Uh Oh... Async Error Handling
Postman HTTPS Issues
Property 'param' does not exist on type 'AlternativeValidationError'
SerializeErrors' not assignable to the same property in base type 'CustomError'
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
Reminder on Password Hashing
Adding Password Hashing
Comparing Hashed Password
Mongoose Pre-Save Hooks
Note on Password Hashing
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
Scope of Testing
Testing Goals
Testing Architecture
Index to App Refactor
A Few Dependencies
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
Auth Helper Function
Testing Non-Authed Requests
Replacing --only=prod Install Flag
Required MongoMemoryServer Updates
Cookie Request is Possibly Undefined Error
No Overload Matches This Call Error with Cookie
GlobalThis has no index signature TS Error
Starting the React App
Reminder on Server Side Rendering
Basics of Next JS
Building a Next Image
Running Next in Kubernetes
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
Fetching Data During SSR
Why the Error?
Two Possible Solutions
Cross Namespace Service Communication
When is GetInitialProps Called?
On the Server or the Browser
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
Building the Header
Conditionally Showing Links
Signing Out
Suggestion Regarding a Default Export Warning
Small Update for Custom Webpack Config
A note about ECONNREFUSED errors
Ingress-Nginx Namespace and Service - Important Update
Error: Invalid <Link> with <a> child
React App Catchup & Checkpoint
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
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
A Required Session Fix and a Global Signin Reminder
What Now?
Three Important Items
Creating a NATS Streaming Deployment
Big Notes on NATS Streaming
Building a NATS Test Project
Port-Forwarding with Kubectl
Publishing Events
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
NATS Server Status - IMPORTANT NOTE
Small Required Command Change
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
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
Quick Note: 'readonly' in Typescript
Publishing Ticket Creation
More on Publishing
NATS Client Singleton
Remember Mongoose?
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
Node Nats Streaming Installation
TS Error - Did you forget to include 'void' in your type argument
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
Test Suite Setup
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?
GlobalThis has no index signature TS Error
Small Update for "Value of type 'typeof ObjectId' is not callable"
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
Testing OCC
One More Test
Who Updates Versions?
Including Versions in Events
Updating Tickets Event Definitions
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
Heads Up Regarding Some Mongoose TS Errors
Test functions cannot both take a 'done' callback and return something Error
Property 'version' is missing TS Errors After Running Skaffold
The Expiration Service
Expiration Options
Initial Setup
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
Skaffold errors - Expiration Image Can't be Pulled
The Payments Service
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
Don't Cancel Completed Orders!
GlobalThis has no index signature TS Error
Important Info About the Next Lecture - Don't Skip
A Few More Pages
Reminder on Data Fetching with Next
Two Quick Fixes
Scaffolding a Form
Sanitizing Price Input
Ticket Creation
Listing All Tickets
Linking to Wildcard Routes
Creating an Order
Programmatic Navigation to Wildcard Routes
The Expiration Timer
Displaying the Expiration
Showing a Stripe Payment Form
Configuring Stripe
Test Credit Card Numbers
Paying for an Order
Filtering Reserved Tickets
Header Links
Rendering a List of Orders
Reminder on Invalid <Link> with <a> child Errors
Module not found: Can't resolve 'prop-types'
Development Workflow
Git Repository Approaches
Creating a GitHub Action
Adding a CI Test Script
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
Configuring the Domain Name
I Really Hope This Works
Next Steps
Tests in GitHub Actions Hang - Jest did not exit
Three Important Changes Needed to Deploy - Do Not Skip!
Why Use Docker?
What is Docker?
Docker for Mac / Windows
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
Building a Dockerfile
Dockerfile Teardown
What's a Base Image?
The Build Process in Detail
A Brief Recap
Rebuilds with Cache
Tagging an Image
Manual Image Generation with Docker Commit
Project Outline
Node Server Setup
A Few Planned Errors
Base Image Issues
A Few Missing Files
Copying Build Files
Container Port Forwarding
Specifying a Working Directory
Unnecessary Rebuilds
Minimizing Cache Busting and Rebuilds
Finished Code and Diagrams
Installing Docker on macOS
Installing Docker with WSL2 on Windows 10/11
Installing Docker on Linux
Buildkit for Docker Desktop
Quick Note for Windows Users
Reminder on Build Kit
How to Get Help
TypeScript Overview
Environment Setup
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
App Overview
Bundling with Parcel
Project Structure
Generating Random Data
Type Definition Files
Using Type Definition Files
Export Statements in TypeScript
Defining a Company
Adding Google Maps Support
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
Important Update About ts-node and Axios
Updated Parcel Instructions
IMPORTANT Info About Faker Installation
Important Note About Google Maps Key
Required Update for New @types Library
Basic knowledge of Javascript and Express is required
Knowledge of React is good, but not needed
You must be familiar and comfortable with the command line
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!
1.2
2 Học viên
275 Khóa học
1253 Đánh giá
Xin chào các bạn, tôi là Nguyễn Đình Cường, một lập trình viên và giảng viên đam mê công nghệ với hơn 15 năm kinh nghiệm trong ngành công nghiệp phần mềm. Tôi tốt nghiệp từ Bưu Chính Viễn Thông và đã từng làm việc cho một số công ty công nghệ hàng đầu như FPT Software và VinGroup. Với chuyên môn chính là phát triển ứng dụng web, tôi đã làm việc với nhiều công nghệ như HTML, CSS, JavaScript, React cho front-end và Node.js, Express, MongoDB cho back-end. Không chỉ dừng lại ở việc viết mã, tôi còn yêu thích tìm hiểu sâu về thiết kế hệ thống và kiến trúc phần mềm. Tôi tin rằng quá trình học lập trình không chỉ đơn thuần là lý thuyết, mà còn là sự trải nghiệm thực tế và giải quyết vấn đề. Trong các khóa học của mình, tôi cố gắng cung cấp cho học viên những bài giảng thú vị và dễ hiểu, cùng với các bài tập thực hành giúp củng cố kiến thức. Tôi hy vọng rằng qua các khóa học của mình, bạn sẽ không chỉ học được cách viết mã, mà còn phát triển tư duy lập trình và kỹ năng giải quyết vấn đề. Hãy cùng nhau khám phá thế giới lập trình và biến ý tưởng của bạn thành hiện thực! Nếu bạn có bất kỳ câu hỏi nào, đừng ngần ngại liên hệ với tôi. Tôi rất vui được hỗ trợ bạn trong hành trình học tập của mình!
Xem chi tiết