与其他 Node.js 框架类似,Nest.js 提供了一整套工具,用于构建强大且可扩展的后端服务。 尽管如此,理解如何在 Nest.js 中高效地实现创建、读取、更新和删除(CRUD)操作至关重要——这些操作是 API 开发中最基本的功能。
本指南将演示如何使用 TypeORM 和 PostgreSQL 数据库构建 Nest.js CRUD REST API。
Nest.js 入门
首先,安装 Nest.js 命令行工具:
npm i -g @nestjs/cli
接下来,通过运行以下命令创建一个新项目:
nest new crud-app
命令行工具会提示您选择包管理器;选择您认为最适合的选项。我们在这里使用 npm,也就是 Node 包管理器。
命令行工具将构建一个基础的 Nest.js 项目,其中包含运行应用程序所需的所有配置文件和初始依赖项。
最后,导航到项目目录并启动开发服务器。
cd crud-app
npm run start
您可以在 GitHub 仓库中找到此项目的源代码。
创建 PostgreSQL 数据库
本教程采用云 PostgreSQL 实例,但您也可以设置本地 PostgreSQL 数据库。 您可以在 Windows、macOS 或 Linux 上安装 PostgreSQL。
设置云 PostgreSQL 实例:


配置数据库连接
在项目根目录下,创建一个 .env 文件并粘贴数据库连接 URL,如下所示:
DATABASE_URL="<your connection url here>"
现在安装以下软件包:
npm install pg typeorm @nestjs/typeorm @nestjs/config
接下来,使用命令行工具创建一个数据库模块。
nest g module database
打开 database/database.module.ts 文件,并添加如下数据库配置代码:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '../users/models/user.entity';@Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],useFactory: async (configService: ConfigService) => ({
type: 'postgres',
url: configService.get('DATABASE_URL'),
entities: [User],
synchronize: true
}),
}),
],
})export class DatabaseModule {}
这个数据库模块负责配置 TypeORM 模块,使用必要的连接参数(数据库 URL)进行数据库连接管理。
另外,它还定义了 User 实体作为配置的一部分,该实体指定了 PostgreSQL 数据库表中存储的数据的结构和属性。
此时,您的代码可能会抛出错误,因为您还没有创建用户实体。 您将在后续步骤中完成此操作。
更新 app.module.ts 文件
最后,更新主应用程序模块,以包含数据库模块的配置。
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './database/database.module';@Module({
imports: [
ConfigModule.forRoot({
envFilePath: '.env',
}),
DatabaseModule,
],controllers: [AppController],
providers: [AppService],
})export class AppModule {}
定义用户模块
users 模块作为一个核心组件,负责封装和管理实现 API 的 CRUD 功能所需的逻辑。
运行此终端命令以创建 API 的用户模块。
nest g module users
在创建用户模块的同时,命令行工具也会自动更新 app.module.ts 文件,以反映所做的更改。 这确保了新创建的模块(用户)能够正确集成到应用程序的模块配置中。
创建用户实体
TypeORM 是一个对象关系映射 (ORM) 库,它通过将 JavaScript 对象映射到数据库表,简化了在 TypeScript 应用中使用数据库的交互。
通过使用 TypeORM 创建用户实体,您可以定义 PostgreSQL 数据库中用户数据的结构和属性。
在 users 目录中,创建一个新的 models/user.entity.ts 文件并添加如下代码。
import { Entity, PrimaryGeneratedColumn, Column, } from "typeorm";@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;@Column()
name: string;@Column()
email: string;
}
用户实体定义了数据库中存储的用户数据的结构。 在本例中,`id` 作为主键列,`name` 和 `email` 列及其相应的属性。
创建 CRUD API 服务
现在,通过运行以下命令创建一个 API 服务,它将管理 CRUD 操作的逻辑:
nest g service users
打开 `user-auth.service.ts` 文件并添加如下代码:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import {User} from './models/user.entity';@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}async findAll(): Promise<User[]> {
return this.userRepository.find();
}async findOne(id: number): Promise<User> {
return this.userRepository.findOne({ where: { id } });
}async create(user: Partial<User>): Promise<User> {
const newuser = this.userRepository.create(user);
return this.userRepository.save(newuser);
}async update(id: number, user: Partial<User>): Promise<User> {
await this.userRepository.update(id, user);
return this.userRepository.findOne({ where: { id } });
}async delete(id: number): Promise<void> {
await this.userRepository.delete(id);
}
}
这个 `UsersService` 类定义了各种专门用于处理 CRUD 操作的 API 方法。 这些方法包括获取所有用户数据、使用 ID 查找特定用户、创建新用户、更新现有用户以及删除数据库中特定用户数据的方法。
为 API 定义控制器
创建一个控制器来管理用户相关操作的 API 端点。
nest g controller users
接下来,将以下代码添加到 `users.controller.ts` 文件中。
import { Controller, Get, Post, Body, Put, Param, Delete, NotFoundException, HttpCode } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './models/user.entity';@Controller('api/users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}@Get()
async findAll(): Promise<User[]> {
return this.usersService.findAll();
}@Post()
@HttpCode(201)
async create(@Body() user: User): Promise<User> {
const createdUser = await this.usersService.create(user);
return createdUser;
}@Put(':id')
async update (@Param('id') id: number, @Body() user: User): Promise<any> {
await this.usersService.update(id, user);
return { message: 'User updated successfully' };
}@Delete(':id')
async delete(@Param('id') id: number): Promise<any> {
const user = await this.usersService.findOne(id);if (!user) {
throw new NotFoundException('User does not exist!');
}await this.usersService.delete(id);
return { message: 'User deleted successfully' };
}
}
控制器管理用户操作的 API 端点。 它处理 GET 请求以检索所有用户、POST 请求以创建新用户、PUT 请求以更新现有用户以及 DELETE 请求以删除用户。
通过利用 `UsersService` 并与 `User` 实体交互,该控制器提供了一个完整的 API,用于管理对数据库中存储的数据的用户相关操作。
更新 users.module.ts 文件
最后,如下更新 `users.module.ts` 文件,以确保合并 `User` 实体和 TypeORM 模块,该模块建立与数据库的连接。
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './models/user.entity';@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService]
})export class UsersModule {}
最后,启动开发服务器以使用 Postman 测试 CRUD 操作。
npm run start
服务器将在端口 3000 上启动,您可以通过以下网址发送 API 请求: http://localhost:3000/api/users。
使用 Nest.js 构建后端应用程序
无论是开发简单的 REST API 还是复杂的 Web 应用程序,Nest.js 都提供了一系列全面的特性和功能,可以帮助您构建可靠且强大的后端系统。
Nest.js 提供了比 Express.js 更结构化的项目开发方法。 得益于其有组织的模块化设计模式,这使得您可以自信地构建、扩展和维护复杂的应用程序。