Nest.js 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架,它结合了现代 JavaScript/TypeScript 的功能和最佳实践。本文将详细介绍 Nest.js 的环境搭建、核心概念与架构以及一些基本功能的开发,帮助你掌握 Nest 后端开发。
Nest.js 简介与环境搭建 什么是 Nest.jsNest.js 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架。它结合了现代 JavaScript/TypeScript 的功能和最佳实践,如依赖注入、面向切面编程、类型检查等。Nest.js 被设计成高度可测试和模块化的,能够轻松地与各种库和工具集成。
Nest.js 的核心目标是为开发者提供一种标准化的方式来创建稳健的 Node.js 应用程序。它提供了大量预定义的装饰器、服务以及工具,简化了开发流程。例如,你可以使用 @Controller
装饰器来定义一个控制器,使用 @Service
装饰器来定义一个服务,并使用 @Module
装饰器来定义一个模块。这使得代码结构清晰,易于维护。
开始使用 Nest.js 之前,你需要搭建好开发环境。这包括安装 Node.js 和 NPM,设置开发工具,以及安装 Nest.js CLI 工具。
安装 Node.js 和 NPM
安装 Node.js 和 NPM(Node.js 包管理器)是运行 Nest.js 应用的前提条件。请访问 Node.js 官方网站 下载并安装最新版本的 Node.js。安装过程中,会自动安装 NPM。
验证安装是否成功,可以通过以下命令检查 Node.js 和 NPM 的版本:
node -v
npm -v
这两个命令分别显示 Node.js 和 NPM 的版本号。
创建第一个 Nest.js 项目
安装好 Node.js 和 NPM 后,接下来需要安装 Nest.js CLI 工具,它可以帮助你快速创建和管理 Nest.js 项目。
-
安装 Nest.js CLI 工具
npm i -g @nestjs/cli
-
创建一个新的 Nest.js 项目
nest new my-nest-app
这条命令会在当前目录下创建一个名为
my-nest-app
的新目录,并在其中初始化一个 Nest.js 项目。项目目录结构如下:my-nest-app/ ├── node_modules/ ├── src/ │ ├── app.controller.ts │ ├── app.module.ts │ └── app.service.ts ├── .gitignore ├── nest-cli.json ├── package.json ├── README.md └── tsconfig.json
node_modules/
:存放项目的依赖库。src/
:存放项目的源代码。app.controller.ts
:定义了应用的主要控制器。app.module.ts
:定义了应用的主要模块。app.service.ts
:定义了应用的服务。.gitignore
:指定 Git 忽略的文件和目录。nest-cli.json
:Nest.js CLI 的配置文件。package.json
:项目的 npm 配置文件。README.md
:项目的 README 文件。tsconfig.json
:TypeScript 编译器设置文件。
控制器(Controller)
在 Nest.js 中,控制器用于处理 HTTP 请求。每个控制器通常与一个或多个路由关联,处理客户端传来的请求,并返回响应。控制器通过装饰器 @Controller
来定义。
import { Controller, Get } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Get()
findAll(): string {
return 'This action returns all users';
}
}
在上面的例子中,UsersController
控制器定义了一个 findAll
方法,它返回一个字符串。@Get()
装饰器表示这个方法处理 HTTP GET 请求。
服务(Service)
服务在 Nest.js 中用于封装业务逻辑。服务可以被多个控制器共享,通常用于执行更复杂的业务逻辑、数据处理或数据库操作。服务通过装饰器 @Injectable
定义。
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserService {
findAll() {
return 'This action returns all users';
}
}
在上面的例子中,UserService
服务定义了一个 findAll
方法,该方法返回一个字符串。@Injectable()
装饰器用于标记该服务可以被依赖注入。
数据库交互(Repository)
Nest.js 支持多种 ORM(对象关系映射)工具,例如 TypeORM、Sequelize 等,它们可以帮助你操作数据库。通常情况下,你使用 @EntityRepository
装饰器来定义一个仓库类。
import { EntityRepository, Repository } from 'typeorm';
import { User } from '../entities/user.entity';
@EntityRepository(User)
export class UserRepository extends Repository<User> {
async find(): Promise<User[]> {
return this.find();
}
}
在上面的例子中,UserRepository
继承了 Repository<User>
类,并定义了一个 find
方法,该方法返回所有用户。
模块(Module)
模块是 Nest.js 应用的组织结构单元。通过模块,你可以定义应用的各个部分,并指定它们所需的配置和依赖关系。模块通过装饰器 @Module
定义。
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
@Module({
providers: [UsersService],
controllers: [UsersController],
})
export class UsersModule {}
在上面的例子中,UsersModule
模块定义了两个属性:providers
和 controllers
。providers
数组包含服务,controllers
数组包含控制器。
装饰器(Decorator)
装饰器是 Nest.js 的一个关键特性,它们用于修饰类、方法或属性,从而添加额外的功能。例如,@Controller
、@Get
、@Post
等都是装饰器。装饰器通常以 @
开头。
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UsersController {
constructor(private readonly userService: UserService) {}
@Get()
findAll(): string {
return this.userService.findAll();
}
}
在上面的例子中,@Controller('users')
装饰器定义了一个控制器,@Get()
装饰器定义了一个 GET 请求处理器。
RESTful API 设计
RESTful API 是一种 Web 服务设计风格,它基于 HTTP 协议,使用标准的 HTTP 方法如 GET、POST、PUT 和 DELETE 来执行 CRUD(创建、读取、更新、删除)操作。在 Nest.js 中,你可以使用装饰器和控制器来定义 RESTful API。
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UserService } from './user.service';
@Controller('users')
export class UsersController {
constructor(private readonly userService: UserService) {}
@Get()
findAll(): string {
return this.userService.findAll();
}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return 'This action adds a new user';
}
}
在上面的例子中,@Get()
和 @Post()
装饰器分别用于定义 GET 和 POST 请求处理器。@Body()
装饰器用于获取请求体中的数据。
数据模型与 ORM
ORM(对象关系映射)是一种将对象模型映射到关系数据库的技术。在 Nest.js 中,常用 ORM 工具有 TypeORM 和 Sequelize。本节以 TypeORM 为例进行说明。
首先,你需要安装 TypeORM:
npm i --save @nestjs/typeorm typeorm
然后,定义一个实体(Entity):
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
定义一个仓库(Repository):
import { EntityRepository, Repository } from 'typeorm';
import { User } from '../entities/user.entity';
@EntityRepository(User)
export class UserRepository extends Repository<User> {
async find(): Promise<User[]> {
return this.find();
}
}
定义一个服务(Service):
import { Injectable } from '@nestjs/common';
import { UserRepository } from '../repositories/user.repository';
@Injectable()
export class UserService {
constructor(private readonly userRepository: UserRepository) {}
async findAll(): Promise<User[]> {
return this.userRepository.find();
}
}
请求验证与错误处理
请求验证通常用于确保客户端发送的数据符合预期格式。Nest.js 通过第三方库 class-validator
和 class-transformer
实现请求验证。
首先,安装相关依赖:
npm i --save class-validator class-transformer
定义一个 DTO(数据传输对象):
import { IsString, IsNotEmpty } from 'class-validator';
import { Transform } from 'class-transformer';
export class CreateUserDto {
@IsString()
@IsNotEmpty()
@Transform(({ value }) => value.trim())
name: string;
}
在控制器中使用 DTO 进行验证:
import { Controller, Post, Body, ValidationPipe } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
@Controller('users')
export class UsersController {
constructor(private readonly userService: UserService) {}
@Post()
create(@Body(ValidationPipe) createUserDto: CreateUserDto) {
return 'This action adds a new user';
}
}
验证管道 ValidationPipe
会自动验证请求体中的数据是否符合 CreateUserDto
定义的规则。
日志记录与调试
日志记录对于调试和监控应用运行状态非常重要。Nest.js 集成了 winston
库进行日志记录。
首先,安装 winston
:
npm i --save winston
然后,在模块中定义日志服务:
import { Module } from '@nestjs/common';
import { LoggerService } from './logger.service';
@Module({
providers: [LoggerService],
exports: [LoggerService],
})
export class LoggerModule {}
定义 LoggerService
服务:
import { Injectable, Scope } from '@nestjs/common';
import { Logger, transports } from 'winston';
@Injectable({ scope: Scope.DEFAULT })
export class LoggerService {
private logger: Logger;
constructor() {
this.logger = new Logger({
level: 'info',
transports: [
new transports.Console({
format: info => `${info.timestamp} ${info.level} ${info.message}`,
}),
],
});
}
debug(message: any) {
this.logger.debug(message);
}
info(message: any) {
this.logger.info(message);
}
warn(message: any) {
this.logger.warn(message);
}
error(message: any) {
this.logger.error(message);
}
}
使用服务记录日志:
import { Injectable } from '@nestjs/common';
import { LoggerService } from '../logger/logger.service';
@Injectable()
export class UserService {
constructor(private readonly loggerService: LoggerService) {}
async findAll() {
this.loggerService.info('Finding all users');
// 业务逻辑...
}
}
高级特性介绍
中间件的使用
中间件在框架中起到拦截请求和响应的作用,可以用于身份验证、日志记录、错误处理等。Nest.js 提供了多种中间件类型,包括全局中间件、管道中间件等。
全局中间件
全局中间件可以处理所有传入的请求。例如:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { LoggerMiddleware } from './logger/logger.middleware';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use((req, res, next) => {
console.log('Request:', req.method, req.url);
next();
});
await app.listen(3000);
}
bootstrap();
管道中间件
管道中间件用于特定控制器或方法。例如:
import { Controller, Get, UseInterceptors } from '@nestjs/common';
import { LoggingInterceptor } from './logger/logger.interceptor';
@Controller('users')
export class UsersController {
@Get()
@UseInterceptors(LoggingInterceptor)
findAll() {
return 'This action returns all users';
}
}
模块化开发
模块化开发是 Nest.js 的核心特性之一,它鼓励你将应用划分为多个独立的模块,每个模块负责不同的功能。模块可以导入其他模块,并使用 @Module
装饰器定义。
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
@Module({
providers: [UsersService],
controllers: [UsersController],
})
export class UsersModule {}
访问令牌与认证
认证是保护应用安全的重要手段。Nest.js 支持多种认证机制,如 JWT(JSON Web Token)。
首先,安装 jsonwebtoken
:
npm i --save jsonwebtoken
定义 JWT 服务:
import { Injectable } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';
@Injectable()
export class AuthService {
private readonly secret = 'mySecretKey';
sign(userId: string): string {
return jwt.sign({ userId }, this.secret);
}
verify(token: string): string {
return jwt.verify(token, this.secret);
}
}
异步处理与 RxJS
Nest.js 支持异步操作和响应式编程。通过 RxJS,你可以处理复杂的异步流,例如从数据库获取数据、处理网络请求等。
首先,安装 rxjs
:
npm i --save rxjs
定义一个异步服务:
import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class UserService {
async findAll(): Promise<string[]> {
return ['Alice', 'Bob', 'Charlie'];
}
findAllAsync(): Observable<string[]> {
return new Observable(observer => {
setTimeout(() => {
observer.next(['Alice', 'Bob', 'Charlie']);
observer.complete();
}, 1000);
});
}
}
在控制器中使用异步服务:
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UsersController {
constructor(private readonly userService: UserService) {}
@Get()
async findAll(): Promise<string[]> {
return this.userService.findAll();
}
@Get('/async')
findAllAsync() {
return this.userService.findAllAsync();
}
}
项目部署与维护
构建与发布
构建 Nest.js 项目通常使用 tsc
(TypeScript 编译器)进行编译。Nest.js CLI 提供了 build
命令来执行构建操作。
nest build
构建完成后,可以在 dist/
目录下找到编译后的 JavaScript 文件。你可以将这些文件部署到生产环境。
服务器部署
部署 Nest.js 应用可以使用多种方案,包括 Node.js 服务器、Docker 容器、Kubernetes 等。
使用 Node.js 服务器
你可以使用 pm2
或 forever
等工具来运行 Node.js 应用。例如:
npm install pm2 -g
pm2 start dist/main.js --name my-nest-app
使用 Docker 容器
使用 Docker 部署可以简化部署流程。首先,创建一个 Dockerfile
:
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD ["node", "dist/main.js"]
然后,使用 Docker 构建和运行:
docker build -t my-nest-app .
docker run -p 3000:3000 my-nest-app
资源优化
资源优化包括代码优化、资源管理和性能调优。例如,可以通过调整缓存策略、使用 CDN、优化数据库查询等方式提升应用性能。
CI/CD 集成
CI/CD(持续集成和持续部署)是现代软件开发的最佳实践。Nest.js 应用可以通过多种 CI/CD 工具进行自动化构建和部署,例如 Jenkins、GitLab CI、GitHub Actions 等。
使用 GitHub Actions
创建一个 .github/workflows/ci.yml
文件:
name: CI
on:
push:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Test
run: npm run test
该配置文件会监听 master
分支上的推送事件,并执行构建和测试操作。
通过以上步骤,你可以充分利用 Nest.js 的强大功能开发高性能的 Node.js 应用,并通过合理的设计和部署,确保应用的稳健性和可维护性。
共同学习,写下你的评论
评论加载中...
作者其他优质文章