
Learn to build a microservices auction app from scratch using .NET and Next.js. Implement dockerized services, identity server login, SignalR live bidding, and RabbitMQ communication with a Tailwind-styled front end.
Review essential prerequisites for this non-beginner course, including docker-based workflow with .NET and Next.js, hardware and Windows requirements, and testing locally via the TryCatch Lancasters GitHub repository.
Set up the development environment by installing a code editor like Visual Studio Code, Docker, Node.js, the .NET SDK, Postman, and GitHub and Git for version control.
Access course assets and source code from the resources and GitHub repository, including postman collections, snippets, architecture specs, and VS code configurations for cloning and navigating commits.
Learn vscode troubleshooting for c# development, including show all commands, developer reload window, switching c sharp dev kit versions, and checking the output logs for guidance.
Explore how microservices, with loosely coupled services that own data, communicate via http and grpc, use a gateway and identity provider, and deploy independently to scale.
Develop and test your first microservice by building a Postgres-backed auction web api with create, read, update, delete operations, using Docker Compose, and validating with Postman checkpoints.
We start building the auction service with a dotnet web api, Postgres database, and entity framework, delivering a basic CRUD for car auctions inside a solution using dotnet cli.
Strip code to a bare .NET 7 web api, disable nullable warnings, keep implicit usings, remove swagger, and run on http localhost 7001 with dotnet watch. Test endpoints with Postman.
Define auction and item entities with a 1-to-1 relationship, plus a status enum, using Entity Framework conventions; configure UTC timestamps and navigation properties in the auction service.
Create the auction dbcontext to interact with a postgres database, configure ef core, add auctions and items db sets, and generate the initial migration, while preparing docker postgres for development.
Learn to spin up a Postgres database server with Docker and a docker-compose.yaml, set a password, map port 5432, persist data, and apply migrations to create auctions and items tables.
Create seed data for the auction service by building a DB initializer, applying migrations, and seeding auctions with Entity Framework Core, then verify with migrations and the Postgres Explorer.
Shape the api response by converting auction and item data into a flattened auction dto, with status as a string, using AutoMapper mappings and create/update dto validations.
Create an api controller for auctions, inject dbcontext and automapper, and expose json endpoints under api/auctions to fetch all auctions or by id with dto mapping.
Learn to use Postman to import a Postman collection I've created, leverage variables for service URLs, run tests and checks, and validate auction endpoints end-to-end with a collection runner.
Add a post endpoint to create auctions, map DTO to an entity with Automapper, save with entity framework, and return 201 with Get Auction by ID location header, validating color.
Add an http put update auction endpoint that fetches the auction by id, updates select properties with optional values, saves changes, and verifies the update via tests.
Add a delete auction endpoint with http delete, validate existence, remove from the context, save changes, and confirm with Postman tests for 200 and 404.
Initialize the git repository and save changes into source control using a dotnet gitignore, then commit and push to a public GitHub repository using main as the branch.
Built a single microservice with a simple CRUD auction API, seeded data in Postgres using Docker compose, and tested endpoints with Postman, while previewing the upcoming search microservice.
Build a second microservice that provides search via a web api, with a dedicated controller and endpoint, using a NoSQL database and simple synchronous http communication between services.
Create a new .NET web api search service backed by MongoDB, delivering paged, filterable, and ordered search results via a single endpoint, while each microservice remains autonomous and data-owned.
Install and run a MongoDB server with Docker Compose, expose port 27017, and persist data with a named volume. Use the MongoDB VSCode extension to connect and prepare entities.
Create an item model in the models folder derived from the MongoDB entity, mirroring the auction DTO, and initialize the search DB with text indexes on make, model, and color.
Seed data from the auction service into the search service's MongoDB by importing JSON, initializing the database, and validating ten seeded items for testing search functionality.
Create a MongoDB-backed search controller to retrieve data via HTTP GET and find queries, sort by make, and return a typed result for Postman testing.
Implement pagination in the search service by adding page number and page size, using a page search, and returning results with page count and total count; test with defaults.
Enhance the search controller by adding a search params object with term, pagination, seller, winner, and order by and filter by options, enabling filtering, sorting, and paging of live auctions.
Explore synchronous messaging between search and auction services using http and gRPC, highlighting dependency risks and the idea of a distributed monolith.
Learn to seed a search service by calling the auction service over http at startup, using a dedicated http client, queryable filtering by date, and AutoMapper projection to a dto.
Implement http polling to make inter-service communication resilient when the auction service is down. Use Polly to retry transient http errors and keep the search service running.
Explore building a simple MongoDB-backed search service within a microservices app, showing synchronous communication between auction and search services, and introduce asynchronous patterns and RabbitMQ service bus.
Explore asynchronous messaging with an event bus to decouple services. Replace synchronous HTTP communication with publish/subscribe fire-and-forget messaging using RabbitMQ, and plan for high availability, retries, and persistence.
Explore RabbitMQ as a message broker that routes published messages via exchanges to queues in a producer-consumer, publish-subscribe model, focusing on fanout with mass transit.
Install RabbitMQ via docker compose to enable asynchronous messaging between services. Use Masstransit conventions to map contracts to exchanges and queues.
Install and configure mass transit with rabbitmq to publish and consume messages, set up endpoints, and share a contracts library for auction created events across .net services.
Define integration events in the auction service, including auction created, auction updated, and auction deleted, to publish via the service bus as asynchronous messages for eventual consistency with search service.
Add an auction created consumer in the search service to map the incoming message to an item with automapper and persist it to MongoDB, using MassTransit conventions.
Publish the auction created event to the service bus after saving the auction, by mapping the auction dto to a created contract and publishing with MassTransit.
Examine how microservices break acid transactions, compare monolith and microservice patterns, and explore failure scenarios across postgres, mongodb, service bus, and outbox retry strategies.
Implement an outbox with MassTransit and EF Core to persist and retry messages when the service bus is down, using Postgres and docker compose.
Configure per-endpoint message retries in RabbitMQ to handle transient MongoDB outages, demonstrating five retries with five-second intervals for the auction created workflow in the search service.
Handle fault queues by simulating a consumer exception for certain models, then use a fault consumer to fix the message and re-publish to update the search service.
Add update and delete consumers to publish auction changes via the outbox to the service bus, and validate end-to-end with tests across the auction and search services.
Publish auction updates via a dedicated endpoint with an outbox for service bus and update the search index in MongoDB using an IMapper-driven consumer for auction updated and deleted events.
Explore how the event bus enables messaging between the auction and search services, with error handling for various messages, as section four ends. We preview adding identity with Identity Server.
Learn to build a local identity server to authenticate API endpoints, issuing tokens via OpenID Connect and OAuth 2.0 for Postman and a client app.
Explore OAuth 2.0 and OpenID Connect, describing authorization flows, tokens, and the roles of resource owner, client, authorization server, and identity provider in enabling secure login and access.
Create and wire a separate identity server project to issue access tokens for the microservices app, using ASP.NET Identity, Entity Framework, and Postgres templates in .NET.
Review and configure a dotnet eight identity service project using Identity Server and ASP.NET Identity, switch to PostgreSQL, and prepare OpenID Connect clients and resources.
Seed data creates Alice and Bob in identity server with ASP.NET Identity and configures the user manager and login flow, while migrating to Postgres and updating migrations.
Review how identity server delivers a login form and logout page via razor pages, using user manager, sign-in manager, and identity server interaction service to authenticate local logins and return URLs.
Add a register page connected to identity server to enable anonymous registration and login. Implement a razor page under account/register with bootstrap styling and routing, enabling anonymous access.
Create a register view model with username, email, password, and full name, wire it to identity server using the user manager, and add a full name claim on success.
Add a register page by reusing the login form, bind email, full name, and password to the model, show a success message post registration, integrating with identity server.
Configure identity server clients for Postman and a Next.js app, enable OpenID Connect with auction scope and profile, and issue access and ID tokens using the resource owner password grant.
Implement a custom profile service for identity server to fetch the user with the user manager and add username and full name as token claims.
Configure authentication on the auction resource server by integrating JWT bearer validation against the Identity Server, including authority, http metadata settings, and token validation parameters, and ensure UseAuthentication precedes UseAuthorization.
Protect resource server endpoints by applying the authorize attribute, enforcing authenticated access for creating, updating, and deleting auctions. Validate user identity with username claims and bearer tokens.
Explore configuring an identity server outside your microservices app to provide authentication via OpenID Connect and OAuth 2, integrate with your API endpoint, and preview a gateway service.
Add a gateway service as a single access point and use a reverse proxy like YARP to forward requests, enable authentication, and support URL rewriting.
Learn to build a gateway service as a reverse proxy using YARP in .NET, configure authentication with JWT Bearer, and load reverse proxy settings from config for internal service routing.
Configure a reverse proxy with YARP in a .NET microservices app by defining routes, transforms, and clusters in appsettings.json, routing auctions and search requests to local services, with authentication options.
Configure the gateway to require authentication for post, put, and delete requests to auctions, using a default authorization policy and OAuth/OpenID credentials, with authentication middleware.
Test the gateway service with Postman to validate token-based authorization and proxy routing as you run Docker Compose up. Learn to verify flows, handle test failures, and prepare for dockerization.
Dockerize the auction, search, and identity services, create auction finished and bid placed contracts, and configure the Next.js client with identity setup.
Add the auction finished and bid placed consumers to the auction service, using mass transit and entity framework to update status, sold amount, and current high bid.
Finish implementing the search service by adding the bid placed consumer and the auction finished consumer, updating the current high bid and auction status in MongoDB for accurate search results.
Add a new Next.js client in the identity service configuration, enabling code and client credentials flows with redirect URIs, offline access, auction app and OpenID Connect scopes for development.
We have implemented and tested the gateway as a reverse proxy to our microservices, while the identity service remains outside the microservices app, and we will dockerize the services next.
Dockerize each service with a per-service Dockerfile and build images using Docker Compose; name images after your Docker account and service, and configure environment variables with depends_on for startup order.
Dockerize your microservices for local development, configure a docker account and hub, and manage images and containers with the Visual Studio Code docker extension for potential cloud deployment via Kubernetes.
Learn to dockerize the auction service with a multi-stage dockerfile using dotnet 9, building, restoring, and publishing before running a runtime image exposed on port 80.
Update the auction service to connect to rabbitmq and postgres in docker, configuring host and credentials with the configuration builder and docker compose networking.
Dockerize the search service by mirroring the auction service setup: craft a customized Dockerfile, configure RabbitMQ and MongoDB, update Docker Compose, build, run, and verify via logs.
Dockerise the identity service by creating a docker file, switching to dotnet eight, and configuring docker compose with a Postgres database and OpenID discovery document.
Explore debugging a .NET service inside a docker container using VSCode launch.json and Docker attach, including inspecting remote IP checks and setting breakpoints to diagnose identity service issues.
Learn how to dockerize the gateway service by creating a Dockerfile, wiring a docker-specific appsettings file, updating routes to docker service names, and configuring docker-compose for the gateway.
Add health checks to the docker compose file to ensure .NET services wait for Postgres, MongoDB, and RabbitMQ readiness, using service_healthy conditions for reliable startup.
Test dockerized microservices with postman, issue bob's token from identity service on localhost:5001, resolve docker issuer mismatch, and verify create, update, and delete flows across gateway, auction, and search services.
Dockerize each microservice to simplify starting and stopping, then decide whether to test now or later using Appendix A guidance, before building the Next.js client application.
Explore building a Next.js client app as a back end for front end (BFF) in a microservices architecture, with server side rendering, token handling, and pre-rendered HTML for SEO.
Create a Next.js client app with create next app, enable TypeScript, ESLint, and Tailwind CSS, use the app router, and run npm run dev to launch on localhost:3000.
Explore how Next.js uses the app router with a page TSX and layout component, alongside global tailwind CSS and essential config files, then clean and initialize a blank project.
Create a top navigation bar for a Next.js app using a React tsx component. Style with flexbox, make it sticky, and place left logo, center search, and right login.
Fetch data from the API on the server-side in a Next.js server component to display auction listings from the search service via the gateway, using server-side fetch and caching.
Learn to build an auction card component in a Next.js react app by wiring data.results to an AuctionCard, passing auction props, using keys, and adopting destructuring for props.
Style auction cards as clickable links with full-width gray panels, a 16:9 video aspect, rounded corners, and overflow hidden, using the Next.js image component with fill and object cover.
Add a countdown timer to each auction card with the react countdown package, create a client component overlaid on the auction image, and style states as finished, ending soon, or live.
Learn to reduce image flicker by converting the image to a client component, implementing a loading state with useState and onLoad, and applying a smooth opacity and scale animation.
Add types to a .NET and Next.js microservices app with TypeScript to boost type safety and intellisense. Create a generic paged result and an auction type with optional fields.
Implement server-side pagination that returns item counts, total pages, and a configurable page size, then add a tailwind-based flow by react pagination component to a Next.js UI.
Implement dynamic pagination by moving the auction get data logic to server actions and converting listings into a client component with local state and page changes.
Show how to add a page size option (4, 8, 12) using filters.tsx props and a button group, update data fetch with the size, and introduce Zstandard for global state.
Use zustand to create a global state store for page number, page size, page count, and search term, replacing prop drilling with setParams and reset.
Refactor the listings to consume data from a Zustand store, optimize rerenders with use shallow, and manage pagination, page size, and query parameters via a unified url-driven data fetch.
Add a nav bar search bar using server and client components connected to a global store to update the url and show results for make, model, or colour.
Implement a client-side search component in the navbar, track input with state, trigger search via enter or click, and reset with a clickable logo using a params store.
Reset the search by syncing the input with the store's initial state, clearing the search term, and refreshing the full results using useEffect to align UI with server-side state.
Add a sorting feature to the filters component with alpha, ending soon, and recently added options, wired to the query via order by in state, updating listings.
Enable filtering of auction results by state using a new filter by in the use params store, defaulting to live with live, ending soon, and finished options.
Add a no results state by using a heading and an empty filter component to display 'no matches for this filter' and offer a reset filters option.
Complete the read side of the user interface with a Next.js client, featuring home, filters, ordering, pagination, and searching, using Zustand for cross-app state and experimental server side actions.
Learn to add authentication to a Next.js client app using OpenID Connect and next-auth, detailing the authorization code flow, token exchange, and encrypted cookies for session management.
Enhance client-side login by sorting by make and model to remove randomness, and update identity server to always include claims in the ID token, then rebuild containers.
Install and configure auth js in a Next.js client to retrieve access tokens via OAuth 2.0 from an identity server and set up the provider.
Implement a client-side login button in the navbar that authenticates via identity server using next-auth, handling redirects, cookies, and session tokens to access the API.
Sign in to obtain the session token from identity server, review cross-site request forgery tokens, and view session data via Next.js with auth js.
Learn how to populate the user’s username in session data using auth.js with JWT, by extending the session via JWT and session callbacks to expose the username in the client.
Build a top-right user actions drop-down in a Next.js app using Flow Bytes React, wiring user props and items like my auctions, sign-out, and a dev-only session link.
Learn how to protect routes in a Next.js app by configuring middleware and a route matcher. Integrate a custom sign-in flow to redirect unauthenticated users to login.
Test API authentication by sending a bearer token to a protected auction endpoint via a client-side auth test button, ensuring login status controls access before implementing crud.
Learn how to extract the access token from the account, move it into the session, and send it in a bearer authorization header to authenticate to the resource server.
Implement secure client-side authentication in a Next.js app using next-auth, with Http-only cookies and tokens encrypted by next-auth secrets.
Continue building the client app with forms using react hook form and leverage next.js file-based routing. Address error handling challenges with experimental server-side actions that can’t be passed to client.
Master routing in Next.js to enable crud operations for auctions, including dynamic routes for details and updates, create auction forms, and advanced filtering with Next.js route params.
Configure seller and winner filters by updating the params store and search controller, wire UI actions to set seller or winner, update the URL, and navigate to listings.
Create a client-side auction form using react hook form with built-in validation, reusable input components, and a date picker, and install the necessary packages to support it.
Build an auction form with react-hook-form by registering fields, validating inputs, handling submit, and using form state such as errors and a loading spinner.
Create a reusable text input component with react hook form's useController for controlled inputs in the auction form. Manage labels, validation, and focus with useEffect and setFocus.
Expand the auction form by adding color, number, and date inputs with grid layout, enforce required validation using react-hook-form, and prepare for a date picker for the auction end date.
Choose between native browser date pickers and a JavaScript date picker for consistency, then build a reusable date input with react date picker and hook form.
Create a reusable fetch wrapper in a Next.js app to centralize server-side API requests (get, post, put, delete), handle authentication headers, and manage errors via a single response handler.
Create an auction by posting form data via the fetch wrapper to the auctions endpoint, then use a try-catch to handle errors and navigate to the auction details page.
Install react hot toast, set up a toaster provider, and display client-side error notifications for unhappy paths using toast error with status and message.
Create an auction details page by fetching data with get details view data, display make, model, year, mileage, image, and a detailed specs table with reserve price and countdown.
Add an edit auction feature by placing an update button on the auction detail page, routing the seller to a shared update form, and updating via a unified update function.
Add a delete auction button on the details page, implement a client-side delete component and server function, handle loading and errors, and test deletion to complete crud in the app.
Explore image upload with cloudinary in a microservices app, compare image service and auction service, ensure authentication, and plan a responsive mobile-first UI with Tailwind while adding the bidding service.
*** Course has now been updated for .Net 8, NextJS 14 and Next-Auth v8***
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.
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.