2025-03-23 | Modern Full-Stack Development with TypeScript (Cont.)
Introduction
This seminar is the second part of the Modern Full-Stack Development with TypeScript seminar.
Part 4: Database Layer with PostgreSQL and Prisma (25 minutes)
PostgreSQL Overview
PostgreSQL is a powerful, open-source object-relational database system with over 30 years of active development.
Key features:
- Strong standards compliance
- Extensibility
- Robust transaction support
- Multi-version concurrency control
- Advanced data types and indexing
Prisma: Modern Database Access
Prisma is an open-source database toolkit that includes:
- Prisma Client: Auto-generated and type-safe query builder
- Prisma Migrate: Declarative data modeling and migration system
- Prisma Studio: GUI to view and edit data
Demo: Defining a Data Model with Prisma
// schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
password String
role Role @default(USER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
orders Order[]
}
model Product {
id Int @id @default(autoincrement())
name String
description String?
price Decimal @db.Decimal(10, 2)
stock Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
orderItems OrderItem[]
}
model Order {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id])
status OrderStatus @default(PENDING)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
items OrderItem[]
}
model OrderItem {
id Int @id @default(autoincrement())
orderId Int
order Order @relation(fields: [orderId], references: [id])
productId Int
product Product @relation(fields: [productId], references: [id])
quantity Int
price Decimal @db.Decimal(10, 2)
}
enum Role {
USER
ADMIN
}
enum OrderStatus {
PENDING
PROCESSING
SHIPPED
DELIVERED
CANCELLED
}
Connecting Prisma to Nest.js
// prisma.service.ts
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
}
Best Practices for Database Management
- Transaction management
- Database migration strategies
- Query optimization
- Connection pooling
- Data validation and integrity
- Seeding strategies for development and testing
Part 5: API Documentation with Swagger (15 minutes)
Swagger Overview
Swagger (OpenAPI) provides a standard, language-agnostic interface to RESTful APIs.
Benefits:
- Interactive documentation
- Client SDK generation
- Standardized API description
- Testing capabilities
Integrating Swagger with Nest.js
// main.ts
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Global validation pipe
app.useGlobalPipes(new ValidationPipe({ transform: true }));
// Swagger setup
const config = new DocumentBuilder()
.setTitle('E-commerce API')
.setDescription('The e-commerce API description')
.setVersion('1.0')
.addTag('e-commerce')
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3000);
}
bootstrap();
Documenting API Endpoints
- Using decorators to document controllers and methods
- Describing data transfer objects (DTOs)
- Adding authentication requirements
- Managing API versions
Part 6: Containerization with Docker (20 minutes)
Docker Overview
Docker provides a way to package applications with all their dependencies into standardized units called containers.
Benefits:
- Consistent environments
- Isolation
- Portability
- Efficiency
- Scalability
Dockerizing Our Application
# Dockerfile
FROM node:16 AS builder
WORKDIR /app
# Copy package files and install dependencies
COPY package*.json ./
RUN npm ci
# Copy source files and build application
COPY . .
RUN npm run build
# Production stage
FROM node:16-alpine
WORKDIR /app
# Copy built application from builder stage
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
# Set environment variables
ENV NODE_ENV production
ENV PORT 3000
# Expose application port
EXPOSE 3000
# Start the application
CMD ["node", "dist/main"]
Docker Compose for Multi-Container Setup
# docker-compose.yml
version: '3.8'
services:
api:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- '3000:3000'
depends_on:
- postgres
environment:
- DATABASE_URL=postgresql://postgres:postgres@postgres:5432/myapp
- NODE_ENV=production
- JWT_SECRET=your_jwt_secret
restart: always
client:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- '80:80'
depends_on:
- api
restart: always
postgres:
image: postgres:14
ports:
- '5432:5432'
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=postgres
- POSTGRES_DB=myapp
volumes:
- postgres-data:/var/lib/postgresql/data
restart: always
volumes:
postgres-data:
Best Practices for Containerization
- Multi-stage builds for smaller images
- Using specific versions for stability
- Security considerations
- Resource constraints
- Container orchestration with Kubernetes
Part 7: Integration and Deployment (15 minutes)
Bringing Everything Together
CI/CD Pipeline Setup
- GitHub Actions or GitLab CI
- Build and test automation
- Docker image creation and pushing
- Deployment to cloud platforms
Environment Management
- Managing environment variables
- Development, staging, and production configurations
- Secrets management
Monitoring and Logging
- Health checks and monitoring
- Centralized logging
- Performance metrics
Deployment Options
- AWS, Google Cloud, or Azure
- Kubernetes clusters
- Cloud database services
- Managed Kubernetes services
Conclusion and Q&A (15 minutes)
Summary of Key Points
- Angular and Nest.js provide a consistent TypeScript experience
- Prisma simplifies database interactions with type safety
- PostgreSQL offers a robust and reliable data store
- Swagger enhances API documentation and testing
- Docker ensures consistency across environments
Resource List
- Official documentation links
- GitHub repositories with sample code
- Recommended books and courses
- Community resources and forums
Open Floor for Questions
Thank you for attending! I’m now open to questions about any aspect of the stack we’ve covered today.
Additional Workshop Materials (Optional Add-ons)
Hands-on Lab Instructions
Step-by-step guides for:
- Setting up the development environment
- Creating an Angular application
- Building a Nest.js API
- Configuring Prisma with PostgreSQL
- Integrating Swagger documentation
- Containerizing with Docker
Code Templates and Starter Projects
- GitHub repository links to starter templates
- Common patterns and solutions
- Best practices implementation examples
Angular Series
- 100 days of Angular: https://github.com/angular-vietnam/100-days-of-angular
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.