A comprehensive NestJS backend application demonstrating best practices with authentication, database management, and modern architectural patterns.
nestjs-api-tutorial/
βββ dist/ # Compiled output
βββ generated/ # Generated files
βββ node_modules/ # Dependencies
βββ prisma/ # Prisma schema and migrations
βββ src/
β βββ auth/ # Authentication module
β βββ bookmark/ # Bookmark module
β βββ prisma/ # Prisma service
β βββ user/ # User module
β βββ app.module.ts # Main application module
β βββ main.ts # Application entry point
βββ test/ # Test files
βββ .env # Environment variables
βββ .gitignore # Git ignore rules
βββ .prettierrc # Prettier config
βββ docker-compose.yml # Docker Compose configuration
βββ eslint.config.mjs # ESLint configuration
βββ nest-cli.json # NestJS CLI config
βββ package-lock.json # Dependency lock file
βββ package.json # Project dependencies
βββ prisma.config.ts # Prisma configuration
βββ README.md # This file
βββ tsconfig.build.json # TypeScript build config
βββ tsconfig.json # TypeScript configuration
βββ tsconfig.test.json # TypeScript test config
- Framework: NestJS (Node.js framework with TypeScript)
- Database: PostgreSQL with Prisma ORM
- Authentication: JWT with Passport.js
- Containerization: Docker Compose
- Validation: DTOs with Pipes
- Configuration: NestJS Config Module
Framework & Core
@nestjs/common(^11.0.1) - Core NestJS framework@nestjs/core(^11.0.1) - NestJS core module@nestjs/platform-express(^11.0.1) - Express platform for NestJS
Authentication & Security
@nestjs/jwt(^11.0.1) - JWT token handling@nestjs/passport(^11.0.5) - Passport.js integrationpassport(^0.7.0) - Passport authentication middlewarepassport-jwt(^4.0.1) - JWT authentication strategypassport-local(^1.0.0) - Local authentication strategyargon2(^0.44.0) - Password hashing library
Database & ORM
@prisma/client(^6.19.0) - Prisma ORM clientprisma(^6.19.0) - Prisma CLI and schema tools
Configuration & Validation
@nestjs/config(^4.0.2) - Configuration managementclass-validator(^0.14.2) - DTO validation decoratorsclass-transformer(^0.5.1) - Class transformation utilitiesdotenv(^17.2.3) - Environment variable management
Utilities
reflect-metadata(^0.2.2) - Reflection metadata supportrxjs(^7.8.1) - Reactive programming library
- JWT-based authentication using Passport.js
- Custom authentication guards with strategy pattern
- Custom decorators for route protection
- Role-based access control implementation
- Prisma ORM for type-safe database operations
- PostgreSQL as primary database
- Automatic schema migrations
- Database seeding capabilities
- DTOs (Data Transfer Objects) for request validation
- Custom pipes for data transformation and validation
- Automatic error handling and response formatting
- Decorator Pattern: Custom decorators for authentication and metadata
- Guard Pattern: Custom guards for authorization with strategy implementation
- Service Layer: Business logic separation
- Module Pattern: Feature-based modular architecture
- Node.js (v18 or higher)
- Docker and Docker Compose
- PostgreSQL (or use Docker Compose)
-
Clone the repository
git clone <repository-url> cd nestjs-api-tutorial
-
Install dependencies
npm install
-
Setup environment variables
cp .env.example .env # Edit .env with your configuration # Required: DATABASE_URL, JWT_SECRET
-
Start PostgreSQL with Docker Compose
npm run db:dev:up
-
Run Prisma migrations and start development
npm run start:dev
Or to manually deploy migrations:
npm run prisma:dev:deploy npm run start:dev
-
(Optional) Restart database
npm run db:dev:restart
This removes, recreates, and deploys all migrations.
The application will be available at http://localhost:3000
The docker-compose.yml file defines a PostgreSQL service for local development.
Start the database:
npm run db:dev:upRestart the database (removes all data and reruns migrations):
npm run db:dev:restartStop the database:
npm run db:dev:rmPrisma configuration is defined in prisma.config.ts. The database URL should be set in your .env file:
DATABASE_URL="postgresql://user:password@localhost:5432/nestjs_db"
# Deploy existing migrations
npm run prisma:dev:deploy
# View database in Prisma Studio
npx prisma studioThe project implements JWT-based authentication using Passport.js:
- Implement authorization logic with strategy pattern
- Protect routes from unauthorized access
- Automatic token validation and extraction
@Public()- Mark routes as publicly accessible@GetUser()- Extract user information from request- Create domain-specific decorators for your needs
Configured in the auth module with:
- Token signing and verification
- Configurable expiration times
- Secret key management via environment variables
Configuration is managed through NestJS Config Module with environment variables:
// Access configuration in services
constructor(private configService: ConfigService) {}
const jwtSecret = this.configService.get<string>('JWT_SECRET');Critical: Prisma client is generated as CommonJS, while NestJS projects typically use ES Modules (ESM). This repository includes a working solution to resolve this conflict. If you encounter module resolution issues in other projects, refer to the implementation here.
To verify module configuration:
- Check
package.jsonfor"type": "module" - Verify
tsconfig.jsonfor module settings - Ensure Prisma generation aligns with your module system
Run tests with:
# Unit tests
npm run test
# Test coverage
npm run test:cov
# Watch mode
npm run test:watchDatabase Management
npm run db:dev:up # Start PostgreSQL container
npm run db:dev:rm # Remove PostgreSQL container
npm run db:dev:restart # Restart database and apply migrations
npm run prisma:dev:deploy # Deploy Prisma migrationsDevelopment
npm run start:dev # Start with watch mode
npm run start # Start application
npm run start:debug # Start with debugging enabled
npm run start:prod # Start production build
npm run build # Build for productionTesting
npm run test # Run unit tests
npm run test:watch # Run tests in watch mode
npm run test:cov # Run tests with coverage report
npm run test:debug # Debug tests
npm run test:e2e # Run end-to-end testsCode Quality
npm run lint # Run ESLint with auto-fix
npm run format # Format code with Prettier- Modular Architecture: Feature-based module organization
- Type Safety: Full TypeScript usage with strict mode
- Validation: DTO and Pipe-based input validation
- Security: JWT authentication with secure token handling
- Error Handling: Centralized exception filters
- Configuration: Environment-based configuration management
- Database: Type-safe ORM with Prisma
- Code Quality: ESLint and Prettier integration
Feel free to contribute by submitting pull requests or opening issues for bugs and feature requests.
This project is licensed under the MIT License.