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 TCB 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_bootstrapfile on windows, it is recommended to use- When creating the
scf_bootstrapfile using vscode on windows, deploying to an HTTP cloud function may result in an error:scf_bootstrapfile 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
Open the CloudBase console Access the Tencent Cloud CloudBase console
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
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
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_bootstrapfile 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.jsonconfiguration - 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.