
Course structure, required tools, getting help and source code.
Master NestJS prerequisites—Node.js, Docker, PostgreSQL—with a code editor, explore GitHub source and per-video changes, and use Table Plus, Visual Studio Code, and TypeScript basics.
Code along in this hands-on NestJS course, pause or slow down as needed, and use the course resources—Q&A, logs, and source code—to master the basics from the start.
So what is NestJS and why would You or Your team use it?
Overview of the project structure and the code quality tools.
A quick overview of terms like DI, IoC and Providers in NestJS.
There are couple of commands that let you start the NestJS app. There are also couple of ways to make requests to the API, like REST Client in VSCode or Postman.
NestJS docs can be confusing about what's a provider, and what does exactly the @Injectable decorator do. We're going to clear any doubts in this video.
Summary of topics covered in this section presented in a visual mind map of concepts.
Build a message formatter that adds timestamps and a logger using dependency injection in NestJS, then wire them into the app service to return the logged message.
Explore building a NestJS message formatter service that prefixes messages with a timestamp. Wire a logger service, register providers, and test the flow from app service to console output.
Get an overview of the complete REST API we'll build in this section. See the final project in action, understand the key features we'll implement, and learn about the core concepts we'll cover while building a real-world task management API with NestJS.
Learn the fundamental principles of REST APIs, including resources, HTTP methods, status codes, and best practices for API design. Essential knowledge for building professional web services.
Discover the importance of modular architecture in NestJS applications. Learn how modules improve code organization, maintainability, and scalability of your REST APIs.
Step-by-step guide to creating and configuring NestJS modules. Learn module registration while following NestJS best practices.
Master NestJS controllers - the backbone of your API endpoints. Learn controller generation, routing basics.
Practical guide to implementing API routes in NestJS. Learn route decoration, handling requests, and sending responses following REST principles.
Learn to create flexible API endpoints using route parameters. Master URL parameter handling, data extraction, and dynamic response generation in NestJS.
Deep dive into NestJS services and the business logic layer. Learn dependency injection, service implementation, and separation of concerns in API development.
Master data modeling in NestJS using TypeScript interfaces and classes. Learn to structure your API data for optimal type safety and code maintainability.
Learn professional data fetching patterns using NestJS services. Implement reusable business logic and maintain clean code architecture.
Master error handling in NestJS REST APIs. Learn to implement proper error responses, status codes, and handle common API error scenarios.
Complete guide to handling POST requests in NestJS. Learn request body handling, data validation, and resource creation following REST best practices.
Master API testing tools - learn to use Postman and VSCode's REST Client with environment variables for efficient API development and testing.
Implement robust data validation in NestJS using built-in validators. Learn to protect your API from invalid data and improve error handling.
Hands-on practice with NestJS validation. Learn to test validation rules, handle validation errors, and improve API reliability.
Master parameter validation and transformation in NestJS. Learn to ensure type safety and data integrity in your API endpoints.
Learn to implement partial resource updates using PATCH requests. Master state management and data updating in REST APIs.
Complete guide to implementing DELETE operations in your REST API. Learn proper status codes, error handling, and resource removal patterns.
Deep dive into REST API update methods. Learn the differences between PUT and PATCH, and when to use each for optimal API design.
Master TypeScript's mapped types to create dynamic, type-safe DTOs in NestJS. Learn how to reduce code duplication and maintain consistency across your data transfer objects using Partial, Pick, and Omit utility types. Essential knowledge for building maintainable APIs.
Learn how to evolve your API from specific status updates to full resource updates using PATCH. Master important service patterns by refactoring methods to accept complete task objects instead of IDs. See how to use Object.assign() for clean updates and discover why passing entire entities to service methods improves code reliability. Essential knowledge for building maintainable NestJS applications.
Master efficient API testing with VSCode's REST Client and Postman. Learn how to use response variables, chain requests, and create reusable request files. See how to capture IDs from POST responses and use them in subsequent requests, eliminating manual ID copying.
Master proper error handling across different application layers in NestJS. Learn how to implement business rules (like status transitions), create custom exceptions, and handle errors appropriately at each layer. See how HTTP layer, controllers, and services interact to enforce business logic and provide meaningful error responses. Essential knowledge for building robust enterprise-grade NestJS applications.
Learn how to properly handle business logic exceptions in your NestJS controllers. Master the pattern of catching domain-specific exceptions and converting them to appropriate HTTP responses. Understand how to maintain clean separation between business logic errors and API responses while providing meaningful error messages to clients.
See why storing data in memory isn't enough for real applications. Learn what tools we'll use to add database storage and see the complete working version of our task manager with PostgreSQL and TypeORM.
Understand proper separation of code and configuration. Learn why and how to manage different configurations across environments (development, testing, production).
Add environment-based configuration to your NestJS app using @nestjs/config. Learn how to install the package, create configuration files, and use ConfigModule. See how to organize your config using registerAs() for better type safety and organization.
Learn how to inject and use ConfigService in your NestJS services. See type-safe configuration access with generics, dot notation for nested config, and default values. Test the configuration changes using REST Client.
When should your NestJS module be static, and when does it need runtime configuration? Learn the key differences using real examples: our simple TasksModule vs ConfigModule and TypeORMModule. Understand the decision-making process that helps you choose the right module type for your use case.
Make your configuration type-safe by adding proper TypeScript types to ConfigService and config objects. Learn how to use interfaces for config sections, create a unified config type, and get better IDE support with proper type hints. No more string-based config access!
Add validation to your environment variables using Joi. Learn how to create validation schemas, set default values, and control validation behavior. See how to catch configuration errors early during application startup instead of runtime.
Show how to set up local database environment using Docker Compose. Quick and reliable way to get started without local installation.
Quick introduction to Docker concepts using PostgreSQL as an example. Learn how to download images, run containers, and configure databases for development. No database installation required on your machine!
Set up TypeORM database configuration properly. Learn how to create type-safe database config, validate environment variables, and register database settings in ConfigModule. Master proper configuration patterns for production-ready database connections.
Compare static and dynamic TypeORM configuration patterns. See how to properly integrate TypeORM with ConfigService using forRootAsync, and understand when to choose each approach.
Learn how to add TypeScript type safety to your NestJS ConfigService without additional runtime overhead. Get better IDE support and catch config errors during development.
Learn how to define your first TypeORM entity to persist data in PostgreSQL. See how decorators map TypeScript classes to database tables, understand column types, and configure automatic table synchronization. Watch your Task interface transform into a fully functional database entity with UUID primary keys and proper column mappings.
Quick but important warning about TypeORM's synchronize option. Learn why it's dangerous in production and why migrations are the professional approach to schema changes.
Configure proper database column types for your entities. See JavaScript/TypeScript types vs PostgreSQL data types, and learn why UUIDs make better primary keys.
Learn about the Repository pattern and why it's crucial for clean architecture. See how it separates data access from business logic, making your code more maintainable and testable.
See how forFeature creates repositories for your entities and makes them available through dependency injection. Understand how this creates clean module boundaries in your NestJS application.
Deep dive into repository injection in NestJS. Learn why @InjectRepository decorator is needed and how it connects with TypeORM's repository system.
Convert our task service to fully leverage TypeORM's repository pattern, implementing proper async/await patterns and database operations. We'll refactor all methods to return Promises and ensure proper error handling.
Create new User entity with timestamps and register it alongside Task entity in TypeORM configuration.
Description: Connect Tasks and Users entities using TypeORM's @ManyToOne and @OneToMany decorators to establish proper database relationships.
Temporarily add userId field to both DTO and entity to keep our API working while we implement the full user system.
Create a TaskLabel entity to allow tasks to have multiple labels, demonstrating a one-to-many relationship pattern.
Add database constraints to prevent duplicate label names within the same task and optimize queries with taskId indexing.
Configure automatic cascade creation and deletion between Tasks and their Labels using TypeORM relationship decorators.
Learn how to validate arrays of objects in DTOs using @ValidateNested, @Type decorators, and create reusable validation rules.
See cascading in action - create task labels automatically by just including them in the task creation payload.
Discover why automatic cascading isn't enough for PATCH operations and prepare for implementing explicit label updates.
Create a service method to handle adding new related records to existing entities, demonstrated with task labels.
Create a dedicated POST endpoint for adding labels to tasks, following REST conventions for nested resources.
Create a utility method to deduplicate label names and use it across task creation and updates.
Filter out existing label names and only save new ones to prevent duplicate task labels.
Fix deletion of entities with relations by using TypeORM's remove() method to properly cascade deletes.
Implement label removal by filtering the labels array, comparing SQL vs in-memory approaches.
Implement status-based filtering of tasks using TypeORM where conditions.
Create reusable pagination types with validation for standardizing paginated API responses.
Transform task listing to return paginated results with metadata about total count and page size.
Add text search capability to filter tasks by matching terms in titles and descriptions using TypeORM Like operator.
Switch from repository methods to query builder for more flexible search with case-insensitive matching and label joins.
Implement label filtering by querying nested relations and using IN clause to match tasks with specified label names.
Optimize label filtering by using a subquery to find tasks with specific labels instead of using a JOIN and IN clause.
Add sort parameters to enable custom ordering of tasks by title, status, and creation date.
Add required packages for implementing JWT authentication, including Passport, bcrypt for password hashing, and their type definitions.
Set up authentication configuration values and schema validation for authentication settings.
Set up the JWT (token generation module) inside the Users Module.
Create the user registration DTO, add password to User entity. We're going to talk about testing the changes we make, and the components we build, without having to build a REST endpoint first.
Create first test file and remove auto-generated test files to start building meaningful authentication tests.
Demonstrate proper unit test structure using Arrange-Act-Assert pattern to validate DTO data.
Improve test suite with specific failure assertions and beforeEach hook for better test organization.
Write failing test for password requirements first, then implement validation using class-validator decorators.
This demonstrates TDD's red-green-refactor cycle: write failing test, implement code to make it pass, then refactor.
Create test helper function to validate different password requirements and implement corresponding regex validations with clear error messages.
The key aspect here is writing focused test cases and helper function to make tests more maintainable and readable.
Create dedicated service for secure password hashing and verification using bcrypt library.
Learn how to use mock and spies to see if dependencies were called inside our methods.
Develop and validate NestJS password service tests by mocking bcrypt compare to validate the verify method, covering the happy path and incorrect password failure.
Verify password in a NestJS PasswordService with a mocked bcrypt compare, ensuring correct parameters are passed and the service returns the mocked true or false result.
Create UserService for database operations with dependency injection of TypeORM repository and PasswordService, preparing for authentication implementation.
This sets up the foundational service for handling user operations.
Add AuthService to handle user registration logic and prevent duplicate emails, preparing for JWT token generation.
This demonstrates separation of concerns by moving authentication logic out of UserService and introducing proper error handling with business rules.
Understand JSON Web Tokens (JWT) using a real-world analogy of metro tickets - how they're issued, validated, and why they're secure.
This makes it relatable and easy to grasp why we use tokens for authentication and how they work under the hood.
Implement generateToken method to create JWT with essential user data in the payload, following security best practices.
Add login method with proper error handling, demonstrating security best practices like timing attack prevention through consistent error messages.
This shows how we avoid leaking information by using the same error message regardless of whether the email or password is incorrect.
Set up registration and login endpoints with proper DTOs and response types, exposing our authentication functionality through a REST API.
Understand why we need more thorough and real-life tests.
Create separate database and authentication settings for E2E testing environment to isolate test data from production.
Create a test setup utility that handles database configuration, cleaning test data, and proper teardown of test resources.
This shows how to properly isolate and manage test environments for reliable end-to-end testing.
Configure end-to-end test environment with proper lifecycle hooks for setup, cleanup, and teardown to ensure isolated test runs.
This demonstrates best practices for E2E testing with consistent database state between tests and proper resource cleanup.
Create end-to-end test for user registration endpoint, verifying successful account creation and proper data handling like password exclusion from response.
Use class-transformer interceptors and @Expose decorators to control which user data is exposed in API responses, ensuring passwords and other sensitive information stay private.
Add E2E test to verify proper error handling when attempting to register with an existing email, ensuring API returns correct 409 Conflict status.
Transform login response from interface to class with proper serialization, demonstrating how to consistently handle data exposure across our API.
Implement an AuthGuard to protect routes by validating JWT tokens from request headers and extracting user information from the payload.
Create secured profile endpoint to allow authenticated users to retrieve their profile data, including proper typing for authenticated requests.
This shows how to use the JWT payload we attached to the request to fetch user-specific data.
Write comprehensive E2E test for protected profile endpoint, covering the full authentication flow from registration through accessing protected data with JWT token.
Learn how to implement application-wide authentication in a NestJS project by configuring a global authentication guard. This video covers removing individual route guards and using NestJS's APP_GUARD to automatically protect all routes, simplifying authentication management across your application.
Discover how to implement a custom @Public() decorator in a NestJS application to easily mark routes that should bypass global authentication. This video demonstrates adding a flexible authentication mechanism using decorators, reflectors, and a global authentication guard, allowing you to selectively expose public endpoints like login, registration, and home routes.
Learn how to enhance your authentication system by including user roles in JWT tokens. This video demonstrates adding a roles property to the user entity, updating the token generation process, and creating a test to verify role inclusion in the authentication flow.
Learn how to create a role-based authorization system using custom decorators and a roles guard. This video demonstrates adding role-specific access to routes, including creating a @Roles() decorator, implementing a roles guard, and adding an admin-only endpoint.
Learn how to write comprehensive end-to-end tests for role-based authentication, including testing an admin-only route. This video demonstrates creating a test that logs in as an admin user and verifies access to a restricted endpoint.
Learn how to write comprehensive E2E tests for role-based authentication by verifying that regular users are forbidden from accessing admin-only routes. This video demonstrates creating a test that checks the proper enforcement of role-based access control.
Learn how to improve your testing infrastructure by adding global validation pipes and preventing unauthorized role assignment during user registration. This video demonstrates updating the test setup to validate input and ensuring that users cannot self-assign admin roles during registration.
Configure a test environment for task creation, including user registration, authentication, and initial task setup using.
Implement a test for security checks to prevent users from accessing tasks created by other users.
Add a custom decorator to get the current user ID easily.
Implement task ownership validation to ensure users can only access, modify, and delete their own tasks.
Add a test for task listing endpoint to return only tasks belonging to the currently authenticated user.
Returning a list of current user tasks only.
Learn how to set up TypeORM migration scripts and configuration for your NestJS project. This video demonstrates adding migration generation and run scripts to your package.json, creating a TypeORM configuration file, and generating an initial migration to set up your database schema.
Learn to install git, initialize a local repository, stage and commit changes, connect to a remote GitHub repository with SSH keys, and push deployments to the DigitalOcean app platform.
Deploy your NestJS app with docker on the DigitalOcean app platform, connect to GitHub, configure resources and port 8080, and add a managed Postgres database.
Implement production migrations with a custom migration run prod using dist js, and prepare a docker deployment on the DigitalOcean app platform with proper env vars and ssl/jwt settings.
Deploy your NestJS API with confidence by reviewing build and deploy logs, verifying endpoints and database connections, monitoring runtime health, and testing secured requests using the provided HTTP file.
Stop building CRUD demos. Start building real APIs that get you hired.
This course takes you from NestJS beginner to production-ready backend developer by building and deploying a complete Task Management API — the kind of portfolio project that stands out to employers.
What you’ll build:
Secure JWT Authentication & Role-Based Access Control
Advanced Filtering, Sorting & Pagination for real-world data handling
Complex Relationships between Tasks, Users & Labels
Comprehensive Unit & End-to-End Testing for reliable deployments
Dockerized Deployment to get your API live and running anywhere
Skills you’ll master:
Clean API Architecture – scalable, maintainable, and easy to extend
Authentication & Security – passwords, JWT, and role-based permissions
Advanced Database Operations – TypeORM + PostgreSQL beyond basic queries
Automated Testing – unit & E2E tests for full confidence in your code
Modern DevOps Workflow – containerization & production deployment
Who this course is for:
→ Node.js developers ready to move beyond basic Express apps
→ Backend devs preparing for technical interviews or senior roles
→ Anyone wanting to learn NestJS with real-world architecture & testing
→ Developers who need to confidently deploy production APIs
Tech stack:
NestJS • TypeScript • PostgreSQL • TypeORM • JWT • Docker
This isn’t just about NestJS syntax — it’s about thinking like a senior backend engineer. By the end, you’ll know exactly how to design, build, test, and deploy APIs that are clean, secure, and ready for real users.