Build a Microservices app with .Net and NextJS from scratch
Microservices is the latest 'buzzword' and hot topic in the web development industry at the moment and nowadays having microservices as part of your skillset is becoming more and more essential. This course aims to teach you how to build a microservices based app using .Net for the backend services and Next.js for the client app. We start from nothing and build up the app until we have a completed app that we can publish to a Kubernetes cluster on the internet.
More
Here are some of the things that are covered in this course:
- Creating several backend services using .Net that provide functionality for the app
- Service to service communication using RabbitMQ and gRPC
- Using IdentityServer as the identity provider.
- Creating a gateway using Microsoft YARP
- Building a client side app with Next.js using the new App Router functionality (since Next.js 13.4)
- Using SignalR for push notifications to the client app
- Dockerizing our different services
- CI/CD workflows using GitHub actions
- Adding ingress controllers
- Publishing the app locally using docker compose
The goals of the main part of this course is to build this app and be able to run and publish everything locally without having to sign up or pay for any cloud services. Once you have completed the main part of the course there are 3 optional Appendixes that cover:
- Unit and integration testing
- Publishing locally to Kubernetes
- Publishing the app to a Kubernetes cluster on the internet
Tools you need for this course
In this course all the lessons are demonstrated using Visual Studio Code, a free (and fantastic) cross platform code editor. You can of course use any code editor you like and any Operating system you like... as long as it's Windows, Linux or Mac. Please ensure that your computer can run Docker as this is a requirement for this course (please see the pre-requisite lesson available as a preview to confirm this).
Is this course for you?
This course is very practical, about 90%+ of the lessons will involve you coding along with me on this project. If you are the type of person who gets the most out of learning by doing, then this course is definitely for you.
On this course we will build an example Auction Application with several services that we will use to provide its functionality. For the client side of things we are using Next.js to take advantage of its client side and server side capabilities which is an excellent fit for what we are building. All you will need to get started is a computer with your favourite operating system that is capable of running Docker, and a passion for learning how to build a microservies based application using .Net and Next.js.
Watch Online Build a Microservices app with .Net and NextJS from scratch
# | Title | Duration |
---|---|---|
1 | Introduction | 04:57 |
2 | Course pre-requisites | 03:50 |
3 | Setting up the developer environment | 05:42 |
4 | Course assets and source code | 04:49 |
5 | VS Code troubleshooting and tips | 05:30 |
6 | Microservices - the big picture | 06:58 |
7 | Introduction to section 2 | 05:27 |
8 | Creating the first micro service | 11:23 |
9 | Reviewing and simplifying the project | 12:25 |
10 | Adding the entity classes | 10:05 |
11 | Adding the Database context class | 13:40 |
12 | Adding a Postgres database server | 10:11 |
13 | Creating seed data | 08:28 |
14 | Shaping the data to return | 09:49 |
15 | Adding an API controller | 11:48 |
16 | Adding a postman collection | 08:17 |
17 | Adding the create auction endpoint | 08:45 |
18 | Adding the update auction endpoint | 06:57 |
19 | Adding the delete auction endpoint | 04:54 |
20 | Saving changes into source control | 06:45 |
21 | Summary | 01:50 |
22 | Introduction to Section 3 | 06:06 |
23 | Creating the second micro services | 09:02 |
24 | Adding the MongoDb server | 08:38 |
25 | Adding the Item model | 07:57 |
26 | Adding seed data | 08:14 |
27 | Adding a search controller | 09:44 |
28 | Paginating the results | 05:10 |
29 | Adding filtering and ordering | 11:43 |
30 | Synchronous messaging | 08:09 |
31 | Adding Http communication to get the data | 16:24 |
32 | Making our Http communication resilient | 15:22 |
33 | Summary of Section 3 | 01:23 |
34 | Introduction to Section 4 | 05:55 |
35 | What is RabbitMQ | 05:47 |
36 | Installing RabbitMQ | 04:34 |
37 | Adding and configuring mass transit | 09:50 |
38 | Adding the contracts | 05:09 |
39 | Adding a consumer to consume a message from the Service bus | 10:45 |
40 | Publishing the Auction Created event to the bus | 08:59 |
41 | What could go wrong? | 10:49 |
42 | Adding a message outbox | 13:26 |
43 | Using message retries | 06:36 |
44 | Consuming fault queues | 09:03 |
45 | Challenge: Adding the update and delete consumers | 04:48 |
46 | Challenge solution | 06:41 |
47 | Summary of section 4 | 01:09 |
48 | Introduction to Section 5 | 07:40 |
49 | OAuth and OpenIDConnect | 10:30 |
50 | Creating the Identity Server project | 05:01 |
51 | Reviewing and configuring our new project | 12:52 |
52 | Seeding data and adding a migration | 17:20 |
53 | Reviewing the login page in identity server | 05:50 |
54 | Adding a register page | 08:12 |
55 | Adding a register page part 2 | 07:33 |
56 | Adding a register page part 3 | 08:34 |
57 | Adding client credentials to allow clients to request a token | 12:54 |
58 | Adding a custom profile service to identity server | 06:11 |
59 | Configuring auth on the resource server | 06:47 |
60 | Configuring the auth endpoints on the resource server | 08:06 |
61 | Summary of section 5 | 02:48 |
62 | Introduction to Section 6 | 04:12 |
63 | Adding the Gateway service | 06:43 |
64 | Adding the Reverse Proxy configuration | 10:17 |
65 | Adding authentication to the Gateway config | 07:23 |
66 | Testing our Gateway service in Postman | 07:55 |
67 | Adding the remaining contracts we need | 04:45 |
68 | Adding the remaining consumers to the Auction Service | 10:31 |
69 | Adding the remaining consumers in the Search Service | 06:20 |
70 | Adding a new client to the Identity service configuration | 07:11 |
71 | Summary of Section 6 | 01:04 |
72 | Introduction to Section 7 | 03:57 |
73 | Creating a docker account | 04:42 |
74 | Dockerizing the Auction Service | 14:09 |
75 | Updating our docker compose file for the Auction Service container | 13:53 |
76 | Dockerising the Search service | 08:52 |
77 | Dockerising the Identity Service | 04:47 |
78 | Debugging a .Net service in a docker container | 11:04 |
79 | Dockerising the Gateway Service | 08:06 |
80 | Testing our docker containers | 11:22 |
81 | Summary of Section 7 | 03:04 |
82 | Introduction to Section 8 | 08:37 |
83 | Creating the NextJS project | 08:05 |
84 | Reviewing and simplifying the NextJS Project | 11:12 |
85 | Creating a nav bar | 14:58 |
86 | Fetching data from the API | 05:31 |
87 | Adding an Auction Card component | 05:02 |
88 | Styling the auction cards | 13:14 |
89 | Adding a countdown timer to the auction card | 13:03 |
90 | Adding loading to the images | 07:04 |
91 | Adding types to the project | 06:21 |
92 | Adding pagination to our list | 08:36 |
93 | Using server functions in client components | 11:28 |
94 | Adding a set page size option | 09:15 |
95 | Using Zustand for state management | 10:04 |
96 | Refactoring our code to use the zustand state | 10:53 |
97 | Adding a search bar | 05:34 |
98 | Adding the search functionality | 08:29 |
99 | Adding a reset to the search function | 04:19 |
100 | Adding the sorting functionality | 08:55 |
101 | Adding the filtering functionality | 04:24 |
102 | Adding a component to display when zero results | 10:51 |
103 | Summary of section 8 | 01:09 |
104 | Introduction to Section 9 | 03:19 |
105 | Before we begin | 04:55 |
106 | Installing Next Auth into our client app | 12:30 |
107 | Adding the login functionality | 06:24 |
108 | Getting the session details in the client | 12:44 |
109 | Populating the session data | 10:40 |
110 | Populating the User actions dropdown | 08:59 |
111 | Protecting routes | 08:55 |
112 | Testing API authentication | 08:08 |
113 | Getting the access token to use to authenticate to our resource server | 11:03 |
114 | Summary of Section 9 | 05:43 |
115 | Introduction to Section 10 | 01:33 |
116 | Routing in NextJS | 06:21 |
117 | Getting the auctions won | 07:39 |
118 | Creating an Auction form | 04:23 |
119 | Creating an Auction form part 2 | 09:39 |
120 | Creating a reusable text input | 08:55 |
121 | Creating the auction form part 3 | 07:28 |
122 | Creating a reusable date input | 09:14 |
123 | Creating a fetch wrapper | 14:07 |
124 | Adding the create auction server action | 10:10 |
125 | Adding react hot toast to display notifications if something goes wrong | 05:07 |
126 | Adding the auction details page content | 09:28 |
127 | Adding the edit auction page | 14:06 |
128 | Adding the delete auction functionality | 08:43 |
129 | Summary of section 10 | 04:26 |
130 | Introduction to Section 11 | 02:35 |
131 | Creating the Bid Service | 08:46 |
132 | Adding the models to the Bid Service | 04:46 |
133 | Adding an API Controller for the bids | 10:33 |
134 | Adding the get bids endpoint | 02:19 |
135 | Adding the auction created consumer | 04:03 |
136 | Testing the bid functionality in Postman | 03:26 |
137 | Adding the DTOs and Automapper | 06:04 |
138 | Adding a producer for the BidPlaced | 07:48 |
139 | Challenge solution | 07:04 |
140 | Adding a Background service for the auction finished event | 15:35 |
141 | What is gRPC? | 05:49 |
142 | Adding gRPC part 1 | 13:57 |
143 | Adding gRPC part 2 | 06:02 |
144 | Adding a gRPC client | 12:03 |
145 | Updating the Gateway service | 03:22 |
146 | Dockerising the BidService | 10:36 |
147 | Summary of Section 11 | 01:00 |
148 | Introduction to Section 12 | 02:14 |
149 | Creating the Notification service | 05:30 |
150 | Adding a SignalR Hub | 05:17 |
151 | Adding the Consumers | 07:50 |
152 | Adding CORS support to the Gateway | 05:20 |
153 | Dockerising the NotificationService | 02:36 |
154 | Updating the Docker compose file | 04:34 |
155 | Summary of section 12 | 00:57 |
156 | Introduction to Section 13 | 00:33 |
157 | Refactoring the auctions into a zustand store | 09:54 |
158 | Updating the Auction cards with the current high price | 05:26 |
159 | Getting the bids for an auction | 03:25 |
160 | Creating a bid item | 09:57 |
161 | Creating a bid store | 09:50 |
162 | Creating a bid form | 14:33 |
163 | Updating the error handling | 06:29 |
164 | Adding conditionals to the form and testing | 05:04 |
165 | Adding SignalR to the client app | 14:00 |
166 | Adding the new bid to SignalR | 05:02 |
167 | Adding a toast for an auction created | 06:51 |
168 | Adding a toast for an auction finished event | 08:14 |
169 | Disabling the auction finished form when the auction finishes | 11:46 |
170 | Preventing low bids | 03:45 |
171 | Summary Section 13 | 00:52 |
172 | Introduction to Section 14 | 03:30 |
173 | Preparing the client app | 12:03 |
174 | Creating the Dockerfile for nextjs | 11:44 |
175 | Fixing the identity server issues in docker compose | 15:09 |
176 | Giving the Identity Server a static ip address | 11:42 |
177 | Adding an ingress to Docker compose | 10:34 |
178 | Adding SSL to the ingress | 07:13 |
179 | Final app cleanup and resolving SignalR issue | 12:27 |
180 | End of course summary | 04:55 |
181 | Intro to Appendix A - Testing | 10:01 |
182 | The simplest unit test possible | 13:52 |
183 | Reviewing the code in the Auction controller and what we are testing | 06:00 |
184 | Creating an Auction Repository and interface | 08:23 |
185 | Refactoring the Auctions controller to use the repository | 04:34 |
186 | Mocking things | 06:02 |
187 | Unit testing the GET methods part 1 | 08:49 |
188 | Unit testing the GET methods part 2 | 08:34 |
189 | Unit testing the POST request | 12:15 |
190 | Challenge - Practicing creating unit tests for the other controller methods | 04:19 |
191 | Challenge solution | 06:07 |
192 | Integration testing setup | 08:58 |
193 | Setting up a Custom web application factory for integration testing | 10:02 |
194 | Adding test data to the DB | 07:41 |
195 | Creating an integration test for the GET method part 1 | 11:13 |
196 | Creating an integration test for a GET request part 2 | 10:27 |
197 | Creating an integration test for the POST request | 13:39 |
198 | Challenge - Practicing creating integration tests for the other methods | 01:51 |
199 | Challenge solution | 03:11 |
200 | Testing the Service bus | 10:37 |
201 | Using Collection fixtures to share the DB across test classes | 10:39 |
202 | Intro to Appendix B - Kubernetes | 09:39 |
203 | No вЂdepends on’ in Kubernetes - using Polly to retry instead | 12:55 |
204 | Adding a GitHub action to push our Identity Server image to Docker hub | 15:03 |
205 | Deploying our IdentityServer to a Digital Ocean server | 07:24 |
206 | Configuring the Linux server to host the identity server | 10:48 |
207 | Creating the first Kubernetes manifest for a deployment | 11:13 |
208 | Adding a persistent volume claim | 06:38 |
209 | Adding a load balancer to allow us to connect to the postgres deployment | 04:52 |
210 | Adding a cluster ip our services can use | 02:50 |
211 | Creating a deployment for RabbitMQ | 06:55 |
212 | Creating a Mongodb deployment | 04:40 |
213 | Creating the auction service deployment | 11:23 |
214 | Creating the search service deployment | 05:52 |
215 | Creating the bid service deployment | 04:55 |
216 | Creating the notification service deployment | 04:07 |
217 | Creating the gateway service deployment | 07:11 |
218 | Creating the client app deployment | 07:55 |
219 | Adding an nginx ingress controller for docker-compose | 09:54 |
220 | Adding SSL to the ingress controller | 09:40 |
221 | Fixing Identity Server issues | 16:24 |
222 | Introduction to Appendix C | 02:55 |
223 | Kubernetes secrets | 06:46 |
224 | Using a manifest to create secrets | 06:34 |
225 | Updating the rest of the secrets | 10:08 |
226 | Adding a workflow to deploy our Auction service | 09:22 |
227 | Creating a kubernetes cluster on Digital Ocean | 06:00 |
228 | Connecting to our new kubernetes cluster | 07:07 |
229 | Creating a workflow to deploy our manifests automatically | 07:39 |
230 | Dev resources and prod resources | 06:38 |
231 | Creating the other deployment workflows for the other services | 09:41 |
232 | Deploying the secrets and the ingress controller | 06:15 |
233 | Deploying our manifests via github actions | 08:09 |
234 | Checking our deployment | 03:37 |
235 | Getting a domain name to point at our Load balancer | 07:42 |
236 | Tying up the loose ends part 1 | 13:49 |
237 | Tying up the loose ends part 2 | 04:52 |
238 | Adding SSL to our deployment part 1 | 09:33 |
239 | Adding SSL to our deployment part 2 | 09:11 |
240 | Finishing up the deployment | 08:12 |