Microservices with Node JS and React
Build, deploy, and scale an E-Commerce app using Microservices built with Node, React, Docker and Kubernetes
What you will learn?
- 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!
Your trainer
Stephen Grider
Stephen Grider has been building complex Javascript front ends for top corporations in the San Francisco Bay Area. With an innate ability to simplify complex topics, Stephen has been mentoring engineers beginning their careers in software development for years, and has now expanded that experience onto Udemy, authoring the highest rated React course. He teaches on Udemy to share the knowledge he has gained with other software engineers. Invest in yourself by learning from Stephen's published courses.
662 lessons
Easy to follow lectures and videos covering subject details.
54 hours
This course includes hours of video material. Watch on-demand, anytime, anywhere.
Certificate of Completion
You will earn a Certificate of Completion at the end of this course.
Course curriculum
- How to Get Help00:56
- Course Resources00:38
- Join Our Community!00:07
- What Is a Microservice?03:19
- Data in Microservices07:34
- Quiz - Data in Microservices3 questions
- Big Problems with Data05:08
- Sync Communication Between Services06:53
- Event-Based Communication05:19
- A Crazy Way of Storing Data09:48
- Pros and Cons of Async Communication06:15
- Important - Optional Boilerplate00:31
- App Overview05:44
- Project Setup04:57
- Posts Service Creation08:18
- Testing the Posts Service04:04
- Implementing a Comments Service08:22
- Quick Comments Test03:57
- Note on the React App00:20
- Suggestion Regarding a Default Export Warning00:27
- React Project Setup05:00
- Building Post Submission09:54
- Handling CORS Errors04:08
- Fetching and Rendering Posts10:04
- Creating Comments08:09
- Displaying Comments07:23
- Completed React App00:13
- Request Minimization Strategies04:54
- An Async Solution07:16
- Common Questions Around Async Events04:14
- Event Bus Overview05:14
- Important Note about Node v15 and Unhandled Promise Rejections00:23
- A Basic Event Bus Implementation05:22
- Emitting Events05:18
- Emitting Comment Creation Events03:45
- Receiving Events04:33
- Creating the Data Query Service04:42
- Parsing Incoming Events07:02
- Using the Query Service07:09
- Adding a Simple Feature04:46
- Issues with Comment Filtering07:43
- A Second Approach05:37
- How to Handle Resource Updates04:45
- Creating the Moderation Service04:52
- Adding Comment Moderation04:26
- Reminder about Node v15 and Error Catching00:11
- Handling Moderation05:29
- Updating Comment Content04:58
- A Quick Test05:57
- Rendering Comments by Status03:26
- Dealing with Missing Events10:23
- Required Node v15+ Update for Query Service00:17
- Implementing Event Sync06:11
- Event Syncing in Action04:16
- Deployment Issues06:55
- Why Docker?02:55
- Why Kubernetes?05:47
- Don't Know Docker? Watch This.01:17
- Note About Docker Build Output and Buildkit00:44
- Dockerizing the Posts Service04:02
- Review Some Basic Commands05:23
- Important Note Regarding Node v1700:31
- Dockering Other Services03:01
- Warning on Docker Desktop for Linux00:37
- Installing Kubernetes03:19
- IMPORTANT Note for Minikube and MicroK8s Users00:47
- A Kubernetes Tour09:45
- Important Kubernetes Terminology02:51
- Notes on Config Files03:11
- Creating a Pod06:41
- ErrImagePull, ErrImageNeverPull and ImagePullBackoff Errors00:35
- Understanding a Pod Spec05:15
- Common Kubectl Commands04:44
- A Time-Saving Alias02:26
- Introducing Deployments03:27
- Creating a Deployment06:11
- Common Commands Around Deployments04:35
- Updating Deployments06:02
- Preferred Method for Updating Deployments05:42
- Networking With Services04:15
- Creating a NodePort Service07:52
- Accessing NodePort Services05:09
- Setting Up Cluster IP Services03:12
- Building a Deployment for the Event Bus05:35
- Adding ClusterIP Services07:37
- How to Communicate Between Services04:09
- Updating Service Addresses06:27
- Verifying Communication05:00
- Adding Query, Moderation and Comments09:57
- Testing Communication05:29
- Load Balancer Services05:13
- Load Balancers and Ingress06:38
- Important - DO NOT SKIP - Ingress Nginx Installation Info00:30
- Installing Ingress-Nginx07:40
- Ingress v1 API Required Update00:29
- Writing Ingress Config Files04:47
- Important Note About Port 8001:12
- Hosts File Tweak06:15
- Important Note to Add Environment Variable00:31
- Deploying the React App06:09
- Unique Route Paths06:55
- Final Route Config06:32
- Introducing Skaffold03:08
- Skaffold Setup09:17
- First Time Skaffold Startup01:00
- A Few Notes on Skaffold06:30
- Big Ticket Items15:11
- App Overview08:53
- Resource Types03:23
- Service Types03:37
- Events and Architecture Design03:48
- Note on Typescript00:20
- Auth Service Setup04:51
- Auth K8s Setup08:15
- Adding Skaffold05:36
- Note on Code Reloading00:08
- Ingress v1 API Required Update00:32
- Ingress-Nginx Setup07:19
- Hosts File and Security Warning04:06
- Section 5 Checkpoint00:16
- Note on Remote Development02:51
- Remote Dev with Skaffold06:35
- Free Google Cloud Credits00:16
- Google Cloud Initial Setup02:43
- Kubernetes Cluster Creation03:59
- Kubectl Contexts03:49
- Initializing the GCloud SDK05:03
- Installing the GCloud Context04:17
- Updating the Skaffold Config04:34
- More Skaffold Updates01:06
- Creating a Load Balancer05:12
- Final Config and Test06:25
- Creating Route Handlers05:40
- Scaffolding Routes04:05
- Adding Validation08:38
- Handling Validation Errors06:18
- Postman HTTPS Issues00:11
- Surprising Complexity Around Errors06:06
- Other Sources of Errors04:17
- Solution for Error Handling04:50
- Building an Error Handling Middleware07:38
- Communicating More Info to the Error Handler05:23
- Encoding More Information In an Error04:35
- Subclassing for Custom Errors08:17
- Determining Error Type03:10
- Converting Errors to Responses10:12
- Moving Logic Into Errors08:36
- Verifying Our Custom Errors08:34
- Final Error Related Code10:19
- How to Define New Custom Errors05:01
- Uh Oh... Async Error Handling05:49
- Section 7 Checkpoint00:16
- Creating Databases in Kubernetes08:25
- Connecting to MongoDB07:53
- Understanding the Signup Flow04:25
- Getting TypeScript and Mongoose to Cooperate05:21
- Creating the User Model04:54
- Type Checking User Properties06:01
- Adding Static Properties to a Model06:00
- Defining Extra Document Properties04:53
- What's That Angle Bracket For?03:52
- User Creation06:47
- Proper Error Handling07:25
- Note on Password Hashing00:37
- Reminder on Password Hashing04:58
- Adding Password Hashing06:57
- Comparing Hashed Password02:54
- Mongoose Pre-Save Hooks05:53
- Section 8 Checkpoint00:16
- Fundamental Authentication Strategies08:58
- Huge Issues with Authentication Strategies07:32
- So Which Option?02:58
- Solving Issues with Option #208:26
- Reminder on Cookies vs JWT's06:21
- Microservices Auth Requirements11:00
- Issues with JWT's and Server Side Rendering09:58
- Cookies and Encryption04:51
- Adding Session Support03:11
- Generating a JWT08:29
- JWT Signing Keys04:56
- Securely Storing Secrets with Kubernetes02:13
- Creating and Accessing Secrets09:18
- Accessing Env Variables in a Pod05:18
- Common Response Properties04:41
- Formatting JSON Properties10:38
- The Signin Flow07:49
- Common Request Validation Middleware05:33
- Sign In Logic06:49
- Quick Sign In Test01:53
- Current User Handler03:01
- Returning the Current User08:55
- Signing Out02:48
- Creating a Current User Middleware06:55
- Augmenting Type Definitions07:46
- Requiring Auth for Route Access07:46
- Section 9 Checkpoint00:22
- Scope of Testing04:28
- Testing Goals04:32
- Testing Architecture07:51
- Index to App Refactor02:54
- A Few Dependencies03:33
- Required MongoMemoryServer Updates00:25
- Test Environment Setup08:12
- Our First Test06:24
- An Important Note01:31
- Testing Invalid Input05:13
- Requiring Unique Emails01:45
- Changing Node Env During Tests05:43
- Tests Around Sign In Functionality06:26
- Testing Sign Out04:31
- Issues with Cookies During Testing05:18
- Easy Auth Solution03:03
- globalThis has no index signature TS Error00:16
- Auth Helper Function07:12
- Testing Non-Authed Requests01:44
- Section 10 Checkpoint00:35
- Starting the React App02:11
- Reminder on Server Side Rendering03:38
- Suggestion Regarding a Default Export Warning00:30
- Basics of Next JS05:24
- Building a Next Image04:28
- Running Next in Kubernetes10:12
- Small Update for Custom Webpack Config00:19
- Note on File Change Detection04:26
- Adding Global CSS05:09
- Adding a Sign Up Form03:11
- Handling Email and Password Inputs03:42
- Successful Account Signup05:12
- Handling Validation Errors06:53
- The useRequest Hook06:59
- Using the useRequest Hook03:40
- An onSuccess Callback05:37
- Overview on Server Side Rendering06:47
- A note about ECONNREFUSED errors00:24
- Fetching Data During SSR05:07
- Why the Error?09:00
- Two Possible Solutions07:04
- Cross Namespace Service Communication07:45
- When is GetInitialProps Called?06:46
- On the Server or the Browser02:01
- Ingress-Nginx Namespace and Service - Important Update00:19
- Specifying the Host08:23
- Passing Through the Cookies04:01
- A Reusable API Client07:05
- Content on the Landing Page02:01
- The Sign In Form03:12
- A Reusable Header05:00
- Moving GetInitialProps02:11
- Issues with Custom App GetInitialProps06:42
- Handling Multiple GetInitialProps06:07
- Passing Props Through03:03
- Building the Header05:05
- Conditionally Showing Links05:58
- Signing Out04:36
- React App Catchup & Checkpoint00:51
- Shared Logic Between Services04:34
- Options for Code Sharing04:46
- NPM Organizations04:27
- Publishing NPM Modules04:06
- Project Setup07:34
- Typo in package.json "files" Field - Do Not Skip00:12
- An Easy Publish Command07:26
- Relocating Shared Code07:29
- Updating Import Statements05:16
- Updating the Common Module05:34
- Section 12 Checkpoint00:25
- Ticketing Service Overview03:03
- Project Setup05:24
- Running the Ticket Service06:05
- Mongo Connection URI08:13
- Quick Auth Update01:47
- Test-First Approach04:19
- Creating the Router04:56
- Adding Auth Protection08:04
- Faking Authentication During Tests07:09
- A Required Session Fix and a Global Signin Reminder00:15
- Building a Session05:39
- Testing Request Validation04:12
- Validating Title and Price04:09
- Reminder on Mongoose with TypeScript07:12
- Defining the Ticket Model03:48
- Creation via Route Handler08:21
- Testing Show Routes06:52
- Unexpected Failure!05:29
- What's that Error?!08:57
- Better Error Logging05:11
- Complete Index Route Implementation06:31
- Ticket Updating06:15
- Handling Updates04:15
- Permission Checking06:49
- Final Update Changes09:04
- Manual Testing05:36
- Section 13 Checkpoint00:35
- What Now?02:50
- NATS Streaming Server Notice00:23
- Three Important Items04:34
- Creating a NATS Streaming Deployment06:25
- Big Notes on NATS Streaming09:53
- Building a NATS Test Project07:31
- Port-Forwarding with Kubectl04:40
- Publishing Events06:20
- Small Required Command Change00:22
- Listening For Data06:55
- Accessing Event Data06:56
- Client ID Generation04:48
- Queue Groups07:28
- Manual Ack Mode09:51
- Client Health Checks09:45
- Graceful Client Shutdown06:42
- Core Concurrency Issues12:56
- Common Questions08:08
- [Optional] More Possible Concurrency Solutions16:42
- Solving Concurrency Issues20:05
- Concurrency Control with the Tickets App09:40
- Event Redelivery04:34
- Durable Subscriptions08:59
- Section 14 Checkpoint00:35
- Reusable NATS Listeners04:32
- The Listener Abstract Class09:27
- Extending the Listener05:53
- Quick Refactor03:17
- Leveraging TypeScript for Listener Validation05:28
- Subjects Enum03:28
- Custom Event Interface02:26
- Enforcing Listener Subjects07:22
- Quick Note: 'readonly' in Typescript00:25
- Enforcing Data Types03:53
- Where Does this Get Used?02:49
- Custom Publisher08:11
- Using the Custom Publisher03:50
- Awaiting Event Publication04:28
- Common Event Definitions Summary06:26
- Updating the Common Module07:35
- Restarting NATS02:09
- Section 15 Checkpoint00:35
- Publishing Ticket Creation03:48
- More on Publishing03:19
- NATS Client Singleton05:24
- Node Nats Streaming Installation00:09
- Remember Mongoose?04:57
- TS Error - Did you forget to include 'void' in your type argument00:17
- Singleton Implementation09:04
- Accessing the NATS Client04:28
- Graceful Shutdown06:55
- Successful Listen!03:23
- Ticket Update Publishing04:28
- Failed Event Publishing07:03
- Handling Publish Failures06:02
- Fixing a Few Tests03:52
- Redirecting Imports05:35
- Providing a Mock Implementation09:09
- Test-Suite Wide Mocks02:12
- Ensuring Mock Invocations09:13
- NATS Env Variables08:00
- Section 16 Checkpoint00:35
- The Orders Service05:02
- Scaffolding the Orders Service04:39
- A Touch More Setup07:32
- Ingress Routing Rules01:53
- Scaffolding a Few Route Handlers09:55
- Subtle Service Coupling06:43
- Associating Orders and Tickets06:49
- Order Model Setup08:52
- The Need for an Enum05:56
- Creating an Order Status Enum08:31
- More on Mongoose Refs02:58
- Defining the Ticket Model07:09
- Order Creation Logic05:45
- Finding Reserved Tickets06:10
- Convenience Document Methods07:37
- Order Expiration Times06:05
- globalThis has no index signature TS Error00:15
- Test Suite Setup02:36
- Small Update for "Value of type 'typeof ObjectId' is not callable"00:21
- Asserting Tickets Exist06:08
- Asserting Reserved Tickets05:05
- Testing the Success Case04:09
- Fetching a User's Orders05:23
- A Slightly Complicated Test12:23
- Fetching Individual Orders04:36
- Does Fetching Work?07:17
- Cancelling an Order04:32
- Can We Cancel?09:12
- Section 17 Checkpoint00:35
- Orders Service Events04:43
- Creating the Events09:23
- Implementing the Publishers03:13
- Publishing the Order Creation05:03
- Publishing Order Cancellation02:33
- Testing Event Publishing05:32
- Section 18 Checkpoint00:35
- Heads Up Regarding Some Mongoose TS Errors00:20
- Time for Listeners!02:12
- Reminder on Listeners01:53
- Blueprint for Listeners03:39
- A Few More Reminders05:26
- Simple onMessage Implementation02:17
- ID Adjustment05:44
- Ticket Updated Listener Implementation04:32
- Initializing the Listeners02:44
- A Quick Manual Test03:16
- Clear Concurrency Issues12:59
- Reminder on Versioning Records06:41
- Optimistic Concurrency Control05:37
- Mongoose Update-If-Current03:46
- Implementing OCC with Mongoose04:02
- Test functions cannot both take a 'done' callback and return something Error00:20
- Testing OCC09:07
- One More Test03:45
- Who Updates Versions?06:29
- Including Versions in Events02:59
- Updating Tickets Event Definitions03:55
- Property 'version' is missing TS Errors After Running Skaffold00:49
- Applying a Version Query07:14
- Did it Work?04:31
- Abstracted Query Method05:42
- [Optional] Versioning Without Update-If-Current18:34
- Testing Listeners04:55
- A Complete Listener Test09:25
- Testing the Ack Call02:09
- Testing the Ticket Updated Listener08:20
- Success Case Testing04:49
- Out-Of-Order Events04:51
- The Next Few Videos03:39
- Fixing a Few Tests06:36
- Listeners in the Tickets Service01:47
- Building the Listener04:59
- Strategies for Locking a Ticket05:28
- Reserving a Ticket03:42
- Setup for Testing Reservation07:00
- Test Implementation04:29
- Missing Update Event06:14
- Private vs Protected Properties06:54
- Publishing While Listening06:42
- Mock Function Arguments09:49
- Order Cancelled Listener06:51
- A Lightning-Quick Test07:28
- Don't Forget to Listen!02:21
- Rejecting Edits of Reserved Tickets06:15
- Section 19 Checkpoint00:35
- The Expiration Service02:38
- Expiration Options07:55
- Initial Setup06:14
- Skaffold errors - Expiration Image Can't be Pulled00:30
- A Touch of Kubernetes Setup07:44
- File Sync Setup02:32
- Listener Creation03:42
- What's Bull All About?03:56
- Creating a Queue09:07
- Queueing a Job on Event Arrival05:10
- Testing Job Processing03:17
- Delaying Job Processing05:23
- Defining the Expiration Complete Event03:50
- Publishing an Event on Job Processing06:27
- Handling an Expiration Event06:00
- Emitting the Order Cancelled Event05:37
- Testing the Expiration Complete Listener05:51
- A Touch More Testing07:20
- Listening for Expiration02:20
- Section 20 Checkpoint00:35
- The Payments Service02:11
- globalThis has no index signature TS Error00:21
- Initial Setup08:45
- Replicated Fields05:57
- Another Order Model!07:30
- Update-If-Current01:17
- Replicating Orders04:07
- Testing Order Creation06:12
- Marking an Order as Cancelled05:39
- Cancelled Testing06:42
- Starting the Listeners03:54
- Payments Flow with Stripe05:10
- Implementing the Create Charge Handler08:32
- Validating Order Payment04:03
- Testing Order Validation Before Payment06:59
- Testing Same-User Validation05:10
- Stripe Setup03:58
- Creating a Stripe Secret03:20
- Creating a Charge with Stripe06:08
- Manual Testing of Payments06:35
- Automated Payment Testing06:27
- Mocked Stripe Client04:23
- A More Realistic Test Setup09:16
- Realistic Test Implementation06:15
- Tying an Order and Charge Together07:18
- Testing Payment Creation06:13
- Publishing a Payment Created Event06:31
- More on Publishing03:18
- Marking an Order as Complete06:18
- Important Info About the Next Lecture - Don't Skip00:51
- Don't Cancel Completed Orders!01:01
- Section 21 Checkpoint00:25
- A Few More Pages06:15
- Reminder on Data Fetching with Next06:09
- Two Quick Fixes05:43
- Scaffolding a Form03:43
- Sanitizing Price Input06:29
- Ticket Creation06:44
- Listing All Tickets07:41
- Linking to Wildcard Routes07:07
- Creating an Order07:25
- Programmatic Navigation to Wildcard Routes04:16
- The Expiration Timer10:54
- Displaying the Expiration01:01
- Showing a Stripe Payment Form03:06
- Configuring Stripe04:23
- Test Credit Card Numbers01:58
- Paying for an Order09:24
- Filtering Reserved Tickets02:27
- Header Links01:47
- Rendering a List of Orders06:20
- Section 22 Checkpoint00:25
- Development Workflow03:39
- Git Repository Approaches06:05
- Creating a GitHub Action07:11
- Adding a CI Test Script02:42
- Running Tests on PR Creation04:48
- Output of Failing Tests05:48
- Running Tests in Parallel07:28
- Verifying a Test Run03:01
- Selective Test Execution05:44
- Deployment Options07:40
- Creating a Hosted Cluster02:39
- Reminder on Kubernetes Context03:32
- Reminder on Swapping Contexts03:56
- The Deployment Plan04:04
- Building an Image in an Action08:40
- Testing the Image Build02:30
- Restarting the Deployment07:17
- Applying Kubernetes Manifests03:27
- Prod vs Dev Manifest Files04:23
- Manual Secret Creation03:39
- Don't Forget Ingress-Nginx!05:31
- Testing Automated Deployment02:51
- Additional Deploy Files07:12
- A Successful Deploy!06:07
- Buying a Domain Name03:10
- Three Important Changes Needed to Deploy - Do Not Skip!01:23
- Configuring the Domain Name05:27
- I Really Hope This Works01:58
- Next Steps04:36
- Section 23 Completed Code00:19
- Why Use Docker?03:43
- What is Docker?02:53
- Docker for Mac / Windows01:57
- Installing Docker on macOS01:10
- Installing Docker with WSL2 on Windows 10/1101:50
- Installing Docker on Linux01:06
- Using the Docker Client05:03
- But Really... What's a Container?08:30
- How's Docker Running on Your Computer?02:44
- Docker Run in Detail01:54
- Overriding Default Commands05:12
- Listing Running Containers04:09
- Container Lifecycle05:16
- Restarting Stopped Containers03:43
- Removing Stopped Containers01:39
- Retrieving Output Logs02:33
- Stopping Containers05:21
- Multi-Command Containers04:16
- Executing Commands in Running Containers02:53
- The Purpose of the 'it' Flag04:35
- Getting a Command Prompt in a Container04:06
- Starting with a Shell02:13
- Container Isolation03:09
- Creating Docker Images02:36
- Buildkit for Docker Desktop00:45
- Building a Dockerfile04:51
- Dockerfile Teardown02:41
- What's a Base Image?05:40
- The Build Process in Detail11:09
- A Brief Recap03:24
- Rebuilds with Cache07:02
- Tagging an Image04:26
- Quick Note for Windows Users00:14
- Manual Image Generation with Docker Commit05:00
- Project Outline02:35
- Node Server Setup05:03
- A Few Planned Errors05:12
- Required Node Base Image Version00:23
- Base Image Issues07:50
- A Few Missing Files03:18
- Copying Build Files04:50
- Container Port Forwarding07:26
- Specifying a Working Directory07:52
- Unnecessary Rebuilds04:16
- Minimizing Cache Busting and Rebuilds04:58
- How to Get Help01:04
- TypeScript Overview06:19
- Environment Setup07:59
- Important Axios Version Information00:12
- A First App04:43
- Executing Typescript Code05:03
- One Quick Change03:35
- Catching Errors with TypeScript07:22
- Catching More Errors!05:15
- Do Not Skip - Course Overview03:36
- Types05:12
- More on Types05:53
- Examples of Types04:48
- Where Do We Use Types?00:49
- Type Annotations and Inference02:03
- Annotations With Variables04:53
- Object Literal Annotations06:53
- Annotations Around Functions05:55
- Understanding Inference03:51
- The Any Type07:47
- Fixing the "Any" Type01:49
- Delayed Initialization03:05
- When Inference Doesn't Work04:37
- More on Annotations Around Functions04:56
- Inference Around Functions06:08
- Annotations for Anonymous Functions01:42
- Void and Never02:49
- Destructuring with Annotations03:35
- Annotations Around Objects07:05
- Arrays in TypeScript05:05
- Why Typed Arrays?04:30
- Multiple Typees in Arrays02:57
- When to Use Typed Arrays00:54
- Tuples in TypeScript04:04
- Tuples in Action05:28
- Why Tuples?03:20
- Interfaces01:26
- Long Type Annotations04:42
- Fixing Annotations With Interfaces04:36
- Syntax Around Interfaces03:31
- Functions in Interfaces04:46
- Code Reuse with Interfaces04:15
- General Plan with Interfaces03:12
- Classes03:47
- Basic Inheritance03:03
- Class Method Modifiers06:41
- Fields in Classes06:18
- Fields with Inheritance04:18
- Where to Use Classes01:09
- Updated Parcel Instructions00:13
- App Overview02:45
- Bundling with Parcel04:54
- Project Structure03:19
- IMPORTANT Info About Faker Installation00:23
- Generating Random Data05:29
- Type Definition Files05:17
- Using Type Definition Files06:20
- Export Statements in TypeScript05:06
- Defining a Company04:43
- Important Note About Google Maps Key00:26
- Adding Google Maps Support07:38
- Required Update for New @types Library00:18
- Google Maps Integration with TypeScript04:06
- Exploring Type Definition Files12:46
- Hiding Functionality06:28
- Why Use Private Modifiers? Here's Why08:25
- Adding Markers09:18
- Duplicate Code02:45
- One Possible Solution06:38
- Restricting Access with Interfaces05:35
- Implicit Type Checks03:26
- Showing Popup Windows06:47
- Updating Interface Definitions07:11
- Optional Implements Clauses06:06
- App Wrapup08:08
- Bonus!00:27
Online Courses
Learning Microservices doesn't have to be hard. Here is our curated list of recommended online courses that will guide you step-by-step in the learning process.
Learn moreBooks
Are you an avid book reader? Do you prefer paperback, or maybe Kindle version? Take a look at our curated list of Microservices related books and take your
YouTube videos
The number of high-quality and free Microservices video tutorials is growing fast. Check this curated list of recommended videos - there is no excuse to stop learning.
Learn more