NestJS is a modular Node.js framework built with TypeScript. It provides a structured architecture using decorators, dependency injection, and metadata-driven programming. The design organizes components for complex applications such as video streaming platforms. Modules, controllers, and providers are isolated for maintainability and testability.

Key Features

NestJS uses TypeScript and Node.js to build scalable, maintainable applications. It structures code with modules, applies metadata using decorators, and manages dependencies through a built-in injection system. It standardizes routing, validation, testing, and communication in both monolithic and distributed systems.

Dependency Injection (DI)

NestJS implements an inversion-of-control (IoC) container for managing dependencies. Providers (services, repositories, etc.) are injected into classes via constructors, reducing tight coupling. The DI system resolves dependencies automatically, ensuring testability and maintainability.

code
import { Injectable } from '@nestjs/common';
code

code
@Injectable()
code
export class UsersService {
code
private users = [];
code

code
findAll() {
code
return this.users;
code
}
code
}

Explanation:

  • Imports the Injectable decorator from NestJS.

  • Declares and exports the UsersService class.

Decorator-Driven Development

Decorators define metadata for classes and methods, streamlining routing, middleware, and validation. For instance, @Controller(), @Get(), and @Post() simplify REST API creation:

code
import { Controller, Get } from '@nestjs/common';
code

code
@Controller('users')
code
export class UsersController {
code
constructor(private usersService: UsersService) {}
code

code
@Get()
code
findAll() {
code
return this.usersService.findAll();
code
}
code
}

Explanation:

  • Imports Controller and Get decorators from NestJS core.
  • Controller defines an HTTP route handler class.
  • Get maps HTTP GET requests to method handlers.

Microservices Support

NestJS natively supports microservices with transporters like TCP, Redis, MQTT, and gRPC. The @MessagePattern() decorator handles event-based communication:

code
import { Controller } from '@nestjs/common';
code
import { MessagePattern } from '@nestjs/microservices';
code

code
@Controller()
code
export class MathController {
code
@MessagePattern({ cmd: 'sum' })
code
accumulate(data: number[]): number {
code
return (data || []).reduce((a, b) => a + b);
code
}
code
}

Explanation:

  • Controller: Marks the class as a NestJS controller.
  • MessagePattern: Defines message-based route handlers for microservice contexts (e.g., TCP, Redis, Kafka).
  • Defines and exports the MathController class.

GraphQL Integration

NestJS provides support for GraphQL via @nestjs/graphql. Resolvers and mutations are defined using decorators:

code
import { Resolver, Query, Args } from '@nestjs/graphql';
code

code
@Resolver('User')
code
export class UsersResolver {
code
@Query(() => [User])
code
async users() {
code
return this.usersService.findAll();
code
}
code
}

Explanation:

  • Declares this class as a GraphQL resolver for the User type.
  • Routes GraphQL operations targeting User fields to methods in this class.

WebSockets & Real-Time Communication

The framework includes @nestjs/websockets for WebSocket gateways, enabling bidirectional event-based communication.

code
import { WebSocketGateway, SubscribeMessage } from '@nestjs/websockets';
code

code
@WebSocketGateway()
code
export class EventsGateway {
code
@SubscribeMessage('message')
code
handleMessage(client: any, payload: string): string {
code
return 'Message received: ' + payload;
code
}
code
}

Explanation:

  • Declares and exports the EventsGateway class.

  • handleMessage(...) processes the 'message' event.

Video-Centric Concepts in NestJS

NestJS supports video-focused functionality through modules, decorators, and built-in utilities. Core features include byte-range streaming, multipart file uploads using interceptors, metadata handling via DTOs, and access control using guards and pipes.

Video Streaming with Byte-Range Support

NestJS supports partial content delivery (HTTP 206) for efficient video streaming. The StreamableFile class and range headers enable adaptive bitrate streaming and seekable playback.

code
import { Controller, Get, Param, Headers, Header } from '@nestjs/common';
code
import { createReadStream, statSync } from 'fs';
code
import { join } from 'path';
code
import { StreamableFile } from '@nestjs/common';
code

code
@Controller('videos')
code
export class VideoController {
code
@Get('stream/:filename')
code
@Header('Accept-Ranges', 'bytes') // Enables range requests
code
async streamVideo(
code
@Param('filename') filename: string,
code
@Headers() headers: { range?: string },
code
) {
code
const videoPath = join(__dirname, 'assets', filename);
code
const { size } = statSync(videoPath);
code
code
if (headers.range) {
code
const CHUNK_SIZE = 10 ** 6; // 1MB chunks
code
const start = Number(headers.range.replace(/\D/g, ''));
code
const end = Math.min(start + CHUNK_SIZE, size - 1);
code
const stream = createReadStream(videoPath, { start, end });
code
return new StreamableFile(stream, {
code
disposition: `inline; filename="${filename}"`,
code
type: 'video/mp4',
code
length: end - start + 1,
code
});
code
}
code
return new StreamableFile(createReadStream(videoPath));
code
}
code
}

Explanation

  • A NestJS wrapper around Node.js Readable streams.
  • Optimizes memory-efficient delivery of large files such as video streams.
  • Extracts the Range header from incoming requests.

File Uploads with Validation

NestJS integrates with Multer for handling multipart/form-data uploads. Custom interceptors enforce file size limits and MIME-type validation.

code
import {
code
Post,
code
UploadedFile,
code
UseInterceptors,
code
Body,
code
Controller
code
} from '@nestjs/common';
code
import { FileInterceptor } from '@nestjs/platform-express';
code
import { diskStorage } from 'multer';
code
import { extname } from 'path';
code

code
@Controller('videos')
code
export class VideoController {
code
@Post('upload')
code
@UseInterceptors(
code
FileInterceptor('video', {
code
storage: diskStorage({
code
destination: './uploads',
code
filename: (req, file, cb) => {
code
const uniqueName = Date.now() + extname(file.originalname);
code
cb(null, uniqueName);
code
},
code
}),
code
limits: { fileSize: 1024 * 1024 * 1024 }, // 1GB max
code
fileFilter: (req, file, cb) => {
code
if (file.mimetype.startsWith('video/')) cb(null, true);
code
else cb(new Error('Only video files allowed!'), false);
code
},
code
}),
code
)
code
async uploadVideo(
code
@UploadedFile() file: Express.Multer.File,
code
@Body() metadata: { title: string; description: string },
code
) {
code
return {
code
message: 'Video uploaded successfully!',
code
filename: file.filename,
code
metadata,
code
};
code
}
code
}
code

Explanation

  • Middleware that extracts multipart/form-data file uploads.
  • Registers the uploaded file under req.file for controller access.

Video Processing with Queues (Bull + Redis)

NestJS integrates with Bull and Redis to offload video processing tasks such as transcoding to background queues. Queues handle workload distribution and async execution outside the request-response cycle. Jobs are added to the queue with parameters like video ID and output formats, enabling scalable and non-blocking media workflows.

code
import { Injectable } from '@nestjs/common';
code
import { InjectQueue } from '@nestjs/bull';
code
import { Queue } from 'bull';
code

code
@Injectable()
code
export class VideoService {
code
constructor(@InjectQueue('video') private videoQueue: Queue) {}
code

code
async transcodeVideo(videoId: string) {
code
await this.videoQueue.add('transcode', {
code
videoId,
code
formats: ['720p', '1080p', '4K'],
code
});
code
}
code
}

Explanation

  • Injects a Bull queue instance named 'video' into the class.
  • Connects to a Redis-backed job queue configured for background processing.

WebSockets for Real-Time Notifications

NestJS uses WebSocket gateways to enable real-time client communication. Events such as video processing completion can trigger server-side messages using `@SubscribeMessage` handlers. The `WebSocketServer` instance emits status updates to subscribed clients over Socket.IO, allowing instant notification delivery.

code
import { WebSocketGateway, SubscribeMessage, WebSocketServer } from '@nestjs/websockets';
code
import { Server } from 'socket.io';
code

code
@WebSocketGateway()
code
export class VideoGateway {
code
@WebSocketServer()
code
server: Server;
code

code
@SubscribeMessage('video_processed')
code
handleProcessed(client: any, payload: { videoId: string }) {
code
this.server.emit(`video_${payload.videoId}`, { status: 'completed' });
code
}
code
}

Explanation

  • Registers the class as a WebSocket gateway.
  • Initializes a WebSocket server and binds it to the application context.
  • Binds a method to handle messages for a specific client-side event name.