Skip to main content

NestJS

NestJS is an enterprise-level backend framework based on TypeScript/Node.js. It employs a modular design, combining OOP (Object-Oriented Programming), FP (Functional Programming), and microservices architecture. With underlying support for Express/Fastify, it provides features like dependency injection, decorator-based routing, and GraphQL integration. It is well-suited for building efficient and maintainable server-side applications, particularly for full-stack TypeScript development.

This guide details how to develop and deploy NestJS applications on CloudBase HTTP cloud functions.

Prerequisites

Before you begin, ensure you meet the following requirements:

  • Node.js environment: version 16.13 or higher (recommended 18.15+)
  • npm or yarn: package manager
  • NestJS CLI: globally install the NestJS command-line tool
  • CloudBase account: with a Tencent Cloud account registered and TCB service activated

Environment Preparation

1. Install NestJS CLI

# Globally install NestJS CLI
npm install -g @nestjs/cli

# Verify installation
nest --version

2. Create a NestJS application

If you already have a NestJS application, you can skip this step.

# Create a new NestJS application
nest new nest-cloudbase-app

# Go to the project directory
cd nest-cloudbase-app

Select a package manager (npm recommended):

? Which package manager would you ❤️ to use? (Use arrow keys)
❯ npm
yarn
pnpm

Application Development

1. Project Structure

After creation, you will have the following project structure:

nest-cloudbase-app/
├── src/
│ ├── app.controller.ts # Application Controller
│ ├── app.module.ts # Application Module
│ ├── app.service.ts # Application Service
│ └── main.ts # Application entry file
├── test/ # Test files
├── package.json
├── tsconfig.json
└── nest-cli.json

2. Modify the application entry file

Edit the src/main.ts file to configure the port to 9000 (CloudBase HTTP cloud function requirement):

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
const app = await NestFactory.create(AppModule);

// Enable CORS
app.enableCors({
origin: true,
credentials: true,
});

// CloudBase HTTP cloud function requires using port 9000
const port = process.env.PORT || 9000;
await app.listen(port, '0.0.0.0');

console.log(`Application is running on: http://localhost:${port}`);
}

bootstrap();

3. Create example API

Create User Module

# Generate User Module
nest generate module users
nest generate controller users
nest generate service users

Edit User Controller

Edit src/users/users.controller.ts:

import { Controller, Get, Post, Body, Param, Put, Delete } from '@nestjs/common';
import { UsersService } from './users.service';

export interface User {
id: number;
name: string;
email: string;
}

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

@Get()
findAll(): User[] {
return this.usersService.findAll();
}

@Get(':id')
findOne(@Param('id') id: string): User {
return this.usersService.findOne(+id);
}

@Post()
create(@Body() user: Omit<User, 'id'>): User {
return this.usersService.create(user);
}

@Put(':id')
update(@Param('id') id: string, @Body() user: Partial<User>): User {
return this.usersService.update(+id, user);
}

@Delete(':id')
remove(@Param('id') id: string): { message: string } {
this.usersService.remove(+id);
return { message: `User ${id} deleted successfully` };
}
}

Edit User Service

Edit src/users/users.service.ts:

import { Injectable, NotFoundException } from '@nestjs/common';

export interface User {
id: number;
name: string;
email: string;
}

@Injectable()
export class UsersService {
private users: User[] = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' },
];

findAll(): User[] {
return this.users;
}

findOne(id: number): User {
const user = this.users.find(user => user.id === id);
if (!user) {
throw new NotFoundException(`User with ID ${id} not found`);
}
return user;
}

create(userData: Omit<User, 'id'>): User {
const newUser: User = {
id: Math.max(...this.users.map(u => u.id), 0) + 1,
...userData,
};
this.users.push(newUser);
return newUser;
}

update(id: number, userData: Partial<User>): User {
const userIndex = this.users.findIndex(user => user.id === id);
if (userIndex === -1) {
throw new NotFoundException(`User with ID ${id} not found`);
}

this.users[userIndex] = { ...this.users[userIndex], ...userData };
return this.users[userIndex];
}

remove(id: number): void {
const userIndex = this.users.findIndex(user => user.id === id);
if (userIndex === -1) {
throw new NotFoundException(`User with ID ${id} not found`);
}
this.users.splice(userIndex, 1);
}
}

4. Add Health Check Endpoint

Edit src/app.controller.ts:

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}

@Get()
getHello(): string {
return this.appService.getHello();
}

@Get('health')
getHealth(): { status: string; timestamp: string } {
return {
status: 'ok',
timestamp: new Date().toISOString(),
};
}
}

Local Testing

1. Start up the development server

# Development Mode Startup
npm run start:dev

# Or Start in Production Mode
npm run build
npm run start:prod

2. Test the API Endpoint

Test the application using curl or Postman:

# Health Check
curl http://localhost:9000/health

# Obtain All Users
curl http://localhost:9000/users

# Obtain Single User
curl http://localhost:9000/users/1

# Create New User
curl -X POST http://localhost:9000/users \
-H "Content-Type: application/json" \
-d '{"name":"Alice Johnson","email":"alice@example.com"}'

# Update User
curl -X PUT http://localhost:9000/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"John Updated","email":"john.updated@example.com"}'

# Delete User
curl -X DELETE http://localhost:9000/users/1

Deployment Configuration

1. Create the scf_bootstrap File

Create the scf_bootstrap file (without extension) in the project root directory:

#!/bin/sh
# Set the port to 9000 (CloudBase HTTP cloud function requirement)
export PORT=9000

# Start NestJS Application
npm run start:prod

2. Set File Permissions

chmod +x scf_bootstrap

3. Optimize package.json

Ensure the package.json contains the correct startup script:

{
"scripts": {
"build": "nest build",
"start": "node dist/main",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main"
}
}

4. Create .gitignore

# Dependencies
node_modules/

# Build Output
dist/
build/

# Log
*.log
npm-debug.log*

# Environment Variables
.env
.env.local
.env.*.local

# IDE
.vscode/
.idea/

# Operating System
.DS_Store
Thumbs.db

Deploy to CloudBase

Method 1: Console Deployment

  1. Open the CloudBase console Access the Tencent Cloud CloudBase console

  2. Create an HTTP cloud function

    • Function Type: Select [HTTP cloud function]
    • Function name: Input nest-app (or custom name)
    • Submission method: Select [Local folder upload]
  3. Upload code

    • Function code: Select your NestJS project root directory
    • Runtime environment: Select Node.js 18.15 (recommended) or other supported versions
    • Automatic Dependency Installation: Enable
  4. Complete deployment Click the "Create" button and wait for the deployment to complete.

Method 2: CLI Deployment (Coming Soon)

Accessing the Application

After successful deployment, you can refer to Accessing Cloud Functions via HTTP to configure custom domain access for

You can test the following APIs:

  • Root Path: / - Express Welcome Page
  • Health Check: /health - View Application Status

Best Practices

1. Environment Variable Management

Configure environment variables in the CloudBase console:

// src/config/database.config.ts
export const databaseConfig = {
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT) || 3306,
username: process.env.DB_USERNAME || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_NAME || 'nestjs_app',
};

2. Log Configuration

// src/main.ts
import { Logger } from '@nestjs/common';

async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: ['error', 'warn', 'log'],
});

const logger = new Logger('Bootstrap');

// ... Other configurations

await app.listen(port, '0.0.0.0');
logger.log(`Application is running on port ${port}`);
}

3. Global Exception Handling

// src/filters/http-exception.filter.ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();

response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.message,
});
}
}

4. Data Validation

# Install verification-related packages
npm install class-validator class-transformer
// src/users/dto/create-user.dto.ts
import { IsEmail, IsNotEmpty, IsString } from 'class-validator';

export class CreateUserDto {
@IsNotEmpty()
@IsString()
name: string;

@IsEmail()
email: string;
}

Frequently Asked Questions

Q: Access after deployment returns 404 error?

A: Check the following points:

  • Verify that the scf_bootstrap file exists and has execute permission
  • Verify the port configuration is set to 9000
  • Check if the application is built correctly (npm run build)

Q: Application fails to start?

A: Common causes:

  • Node.js version is incompatible; it is recommended to use 18.15+
  • Dependency installation failed; check the package.json configuration
  • Insufficient memory; consider optimizing the code or upgrading the function configuration

Q: How do I view application logs?

A: View running logs in the 'cloud function' → 'function details' → 'logs' section of the CloudBase console.

Q: How do I connect to the database?

A: It is recommended to use CloudBase database or other cloud database services:

// Install database-related packages
npm install @nestjs/typeorm typeorm mysql2

// Configure database connection
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
autoLoadEntities: true,
synchronize: process.env.NODE_ENV !== 'production',
}),
],
})
export class AppModule {}

Summary

Through this guide, you have learned how to develop and deploy NestJS applications on CloudBase HTTP cloud functions. NestJS's modular architecture and powerful feature set, combined with CloudBase's cloud-native capabilities, can help you quickly build high-quality enterprise-level applications.

It is recommended to further optimize the application architecture, add database integration, and implement authentication features based on business requirements in actual projects.