Skip to main content

NestJS

NestJS is an enterprise-grade backend framework based on TypeScript/Node.js. It adopts a modular design, combining OOP (Object-Oriented Programming), FP (Functional Programming), and microservices architecture. It supports underlying frameworks like Express/Fastify, providing features such as dependency injection, decorator-based routing, and GraphQL integration. It is ideal for building efficient and maintainable server-side applications, particularly well-suited for full-stack TypeScript development.

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

Prerequisites​

Before you begin, ensure that you have:

  • Node.js environment: Version 16.13 or higher (18.15+ recommended)
  • npm or yarn: Package manager
  • NestJS CLI: Globally install the NestJS command-line tool
  • CloudBase account: Have registered a Tencent Cloud account and activated the CloudBase service

Environment Preparation​

1. Install the NestJS CLI​

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

# Verify the 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​

Once created, 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. Update the application entry file​

Edit the src/main.ts file to configure the port to 9000 (required by CloudBase HTTP cloud functions):

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. Creating an Example API​

Create User Module​

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

Editing 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` };
}
}

Editing 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 development server​

# Starting Up in Development Mode
npm run start:dev

# Or Starting Up in Production Mode
npm run build
npm run start:prod

2. Testing API Endpoints​

Test the application using curl or Postman:

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

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

# Obtain a 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"}'

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

Deployment Configuration​

1. Create the scf_bootstrap File​

💡 Note:

  • When creating the scf_bootstrap file on windows, it is recommended to use
  • When creating the scf_bootstrap file using vscode on windows, deploying to an HTTP cloud function may result in an error: scf_bootstrap file does not exist
  • This error occurs because the script file contains Windows-style carriage returns (^M), causing Linux to fail to recognize the interpreter path correctly. This is a common issue in WSL

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

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

# Start the NestJS Application
npm run start:prod

2. Set File Permissions​

chmod +x scf_bootstrap

3. Optimize package.json​

Ensure that 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/

# Logs
*.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: Deploy via the console​

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

  2. Create an HTTP cloud function

    • Function Type: Selection of HTTP cloud function
    • Function Name: Enter nest-app (or a custom name)
    • Submit method: Select Local folder upload
  3. Upload the code

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

Method 2: CLI Deployment​

For details, see Deploy HTTP cloud function

Access Your Application​

After successful deployment, you can refer to Accessing Cloud Functions via HTTP to set up custom domain access to the

You can test the following endpoints:

  • 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: After deployment, accessing a 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 whether the application is built correctly (npm run build)

Q: Application failed 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 to view application logs?​

A: You can view the runtime logs under Cloud Functions > Function Details > Logs in the CloudBase console.

Q: How to 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 features, combined with CloudBase's cloud-native capabilities, enable you to rapidly build high-quality enterprise-level applications.

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