Nest開發(fā)入門指南
NestJS 是一个高效的服务器端 JavaScript 应用框架,支持依赖注入、面向对象编程和装饰器等特性,帮助开发者构建可维护的结构化代码。本文详细介绍了 NestJS 的安装、创建第一个应用以及基本结构,同时涵盖了 Nest 开发中的关键概念和实践。
Nest框架简介 Nest框架的基本概念NestJS 是一个用于构建高效、可扩展的服务器端 JavaScript 应用程序的框架。它借鉴了 Angular 的设计原则,如依赖注入、面向对象编程和装饰器,使得开发者能够创建结构化、可维护的代码。NestJS 支持 TypeScript,这意味着开发者可以在开发过程中利用强类型系统和静态类型检查,从而提高代码质量。
NestJS 的主要特点包括:
- 依赖注入:NestJS 利用依赖注入来管理应用程序中的依赖关系,这使得代码更加松耦合和可测试。
- 面向对象编程:NestJS 鼓励开发者使用面向对象编程原则来构建应用程序。
- 装饰器:NestJS 使用装饰器来定义服务、控制器、管道、中间件等。
- 模块化:应用程序被分解为多个模块,每个模块可以包含控制器、服务、管道、中间件和子模块。
要开始使用 NestJS,首先需要安装 Node.js 和 npm。请确保你已经安装了 Node.js 的最新版本。你可以通过访问官网 https://nodejs.org/
并按照指示进行安装。
接下来安装 NestJS CLI。NestJS CLI 是一个命令行工具,可以帮助你快速生成 NestJS 应用程序,并提供一些实用的命令来简化开发流程。
安装 NestJS CLI 的步骤如下:
- 打开终端或命令行工具。
-
运行以下命令来全局安装 NestJS CLI:
npm i -g @nestjs/cli
创建一个全新的 NestJS 应用程序非常简单。以下是创建一个新 NestJS 应用程序的基本步骤:
- 打开终端或命令行工具。
-
创建一个新的 NestJS 应用程序:
nest new my-nest-app
这将创建一个新的目录
my-nest-app
,并在其中生成一个基本的 NestJS 应用程序结构。 -
进入新创建的目录:
cd my-nest-app
-
启动应用程序:
npm run start:dev
这将启动开发服务器,并监听端口 3000。你可以在浏览器中访问
http://localhost:3000
来查看默认的 "Hello World" 页面。
示例代码
在 src/app.controller.ts
文件中,你可以看到一个简单的控制器定义:
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
getHello(): string {
return 'Hello World!';
}
}
在 src/app.module.ts
文件中,定义了应用程序的模块:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
imports: [],
controllers: [AppController],
providers: [],
})
export class AppModule {}
Nest应用的基本结构
项目目录结构
一个典型的 NestJS 应用程序目录结构如下:
my-nest-app/
├── /src
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ ├── app.service.spec.ts
│ ├── main.ts
│ └── ...
├── /dist
├── /node_modules
├── .env
├── .gitignore
├── .editorconfig
├── .prettierrc
├── .eslintrc.json
├── nest-cli.json
├── package.json
├── package-lock.json
├── README.md
└── tsconfig.json
/src
是应用程序的主要目录,包含了所有的代码文件。/dist
是编译后的目录。/node_modules
包含了项目依赖的包。.env
文件用于定义环境变量。.gitignore
文件用于指定 Git 版本控制系统忽略的文件或目录。.editorconfig
文件用于定义编辑器的编码规范。.prettierrc
和.eslintrc.json
文件用于配置代码格式化和代码风格检查。nest-cli.json
文件是 NestJS CLI 的配置文件。package.json
文件包含了项目的依赖和脚本。package-lock.json
文件记录了依赖的确切版本。README.md
文件是项目的说明文件。tsconfig.json
文件是 TypeScript 的配置文件。
控制器(Controllers)
控制器是 NestJS 中处理 HTTP 请求的入口点。每个控制器通常包含一组处理 HTTP 请求的方法。控制器方法使用 HTTP 方法装饰器(如 @Get
、@Post
、@Put
、@Delete
)来定义 HTTP 请求的处理。
示例代码
在 src/controllers/app.controller.ts
文件中定义一个简单的控制器:
import { Controller, Get } from '@nestjs/common';
@Controller('app')
export class AppController {
@Get()
getHello(): string {
return 'Hello World!';
}
}
服务(Services)
服务是 NestJS 中用来处理业务逻辑的模块。服务通常不直接处理 HTTP 请求,而是由控制器调用。服务通常是可测试的,并且可以被其他模块重用。
示例代码
在 src/services/app.service.ts
文件中定义一个简单的服务:
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Service: Hello World!';
}
}
模块(Modules)
模块在 NestJS 中用于组织相关的控制器和服务。模块定义了应用程序的结构,并可以通过依赖注入来声明服务和其他模块的依赖关系。
示例代码
在 src/modules/app.module.ts
文件中定义一个简单的模块:
import { Module } from '@nestjs/common';
import { AppController } from './controllers/app.controller';
import { AppService } from './services/app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
路由与中间件
路由定义
路由定义了控制器中的 HTTP 方法与实际 URL 之间的映射关系。NestJS 使用装饰器来定义路由。
示例代码
在 src/controllers/app.controller.ts
文件中定义一个带有路由的控制器:
import { Controller, Get } from '@nestjs/common';
@Controller('app')
export class AppController {
@Get()
getHello(): string {
return 'Hello World!';
}
@Get('about')
about(): string {
return 'This is the About page.';
}
}
中间件介绍
中间件在 NestJS 中用于处理 HTTP 请求的生命周期。中间件可以访问和修改请求和响应,也可以在请求到达控制器之前或之后执行某些操作。NestJS 支持多种中间件,包括自定义中间件和第三方中间件。
示例代码
定义一个简单的中间件:
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...', req.url);
next();
}
}
在模块中使用中间件:
import { Module } from '@nestjs/common';
import { AppController } from './controllers/app.controller';
import { AppService } from './services/app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
使用中间件处理请求
中间件可以用于对请求进行预处理,或者在请求到达控制器之前或之后执行某些操作。例如,可以使用中间件来验证请求头、解析请求体、记录日志等。
示例代码
在控制器中使用中间件:
import { Controller, Get, UseMiddleware } from '@nestjs/common';
@Controller('app')
export class AppController {
@Get()
@UseMiddleware(LoggerMiddleware)
getHello(): string {
return 'Hello World!';
}
}
数据操作与数据库集成
操作数据库
NestJS 提供了多种数据库集成方案,包括 TypeORM、Sequelize、Knex.js 等。TypeORM 是一个流行的 ORM(对象关系映射)库,它支持多种数据库,包括 MySQL、PostgreSQL、SQLite 等。
示例代码
定义一个简单的数据库实体:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
}
定义一个服务来操作数据库:
import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { User } from '../entity/user.entity';
@Injectable()
export class UserService {
constructor(private readonly userRepository: Repository<User>) {}
async createUser(name: string, email: string): Promise<User> {
const user = this.userRepository.create({ name, email });
return this.userRepository.save(user);
}
async findUserById(id: number): Promise<User | null> {
return this.userRepository.findOne({ where: { id } });
}
}
集成TypeORM
TypeORM 可以通过 NestJS 模块轻松集成。以下是集成 TypeORM 的基本步骤:
-
安装 TypeORM 和数据库驱动:
npm install typeorm mysql2 --save
-
在
src/data-source.ts
文件中配置数据源:import { TypeOrmModuleOptions } from '@nestjs/typeorm'; import { User } from './entity/user.entity'; export const typeOrmConfig: TypeOrmModuleOptions = { type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'password', database: 'nestjs_db', entities: [User], synchronize: true, };
-
在应用程序模块中导入 TypeORM 模块:
import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AppController } from './controllers/app.controller'; import { AppService } from './services/app.service'; @Module({ imports: [ TypeOrmModule.forRoot(typeOrmConfig), TypeOrmModule.forFeature([User]), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
在服务中定义函数来连接和查询数据库:
import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { User } from '../entity/user.entity';
@Injectable()
export class UserService {
constructor(private readonly userRepository: Repository<User>) {}
async createUser(name: string, email: string): Promise<User> {
const user = this.userRepository.create({ name, email });
return this.userRepository.save(user);
}
async findUserById(id: number): Promise<User | null> {
return this.userRepository.findOne({ where: { id } });
}
}
接口文档与测试
开发接口文档
NestJS 可以使用 Swagger 来生成 API 接口文档。Swagger 是一个开放的 API 规范,可以用于定义、生成、表示、调试和可视化 RESTful 风格的 Web 服务。
示例代码
安装 Swagger 相关依赖:
npm install @nestjs/swagger swagger-ui-express --save
在应用程序模块中配置 Swagger:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '../entity/user.entity';
import { UserService } from './services/user.service';
import { UserController } from './controllers/user.controller';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
@Module({
imports: [
TypeOrmModule.forRoot(typeOrmConfig),
TypeOrmModule.forFeature([User]),
SwaggerModule.forRoot({
documentBuilder: new DocumentBuilder()
.addBearerAuth()
.build(),
}),
],
controllers: [UserController],
providers: [UserService],
})
export class AppModule {}
在控制器中添加 Swagger 文档:
import { Controller, Get, UseMiddleware } from '@nestjs/common';
import { Swagger, ApiOperation, ApiProperty } from '@nestjs/swagger';
import { User } from '../entity/user.entity';
@Controller('user')
export class UserController {
@Get()
@ApiOperation({ summary: 'Get all users' })
findAll(): User[] {
return this.userService.findAll();
}
}
单元测试与集成测试
NestJS 提供了多种测试工具,包括 Jest 和 Mocha。Jest 是一个流行的 JavaScript 测试框架,支持快照测试、模拟对象等功能。
示例代码
安装 Jest 依赖:
npm install --save-dev jest @nestjs/testing @types/jest
在 src/user.service.spec.ts
文件中编写单元测试:
import { Test, TestingModule } from '@nestjs/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserService],
}).compile();
service = module.get<UserService>(UserService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
it('should create a user', async () => {
const user = await service.createUser('John Doe', 'john.doe@example.com');
expect(user).toBeDefined();
expect(user.name).toBe('John Doe');
expect(user.email).toBe('john.doe@example.com');
});
it('should find a user by ID', async () => {
const user = await service.createUser('Jane Doe', 'jane.doe@example.com');
const foundUser = await service.findUserById(user.id);
expect(foundUser).toBeDefined();
expect(foundUser.name).toBe('Jane Doe');
expect(foundUser.email).toBe('jane.doe@example.com');
});
});
使用Jest进行测试
Jest 提供了多种测试方法,如 expect
、describe
、it
等,可以用来编写测试用例。
示例代码
在 src/controllers/app.controller.spec.ts
文件中编写控制器的测试:
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from '../services/app.service';
describe('AppController', () => {
let controller: AppController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
controller = module.get<AppController>(AppController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
it('should return "Hello World!"', () => {
expect(controller.getHello()).toBe('Hello World!');
});
});
部署与调试
应用打包与部署
NestJS 应用程序可以通过 npm 脚本进行打包和部署。通常,我们使用 npm run build
命令来编译 TypeScript 代码,并使用 npm run start
命令来启动应用程序。
示例代码
在 package.json
文件中定义构建和启动脚本:
{
"scripts": {
"start": "node dist/main.js",
"build": "nest build",
"start:dev": "nest start",
"lint": "tslint -p tsconfig.json"
}
}
运行构建命令:
npm run build
运行启动命令:
npm run start
日志与调试技巧
NestJS 应用程序可以通过多种方式输出日志,包括控制台日志、文件日志等。常见的日志库包括 Winston、Bunyan 等。
示例代码
安装 Winston 日志库:
npm install winston --save
在应用程序中使用 Winston:
import winston from 'winston';
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'app.log' }),
],
});
export { logger };
在服务或控制器中使用日志:
import { Injectable } from '@nestjs/common';
import { logger } from './logger';
@Injectable()
export class AppService {
constructor() {
logger.info('AppService initialized');
}
getHello(): string {
logger.info('Calling getHello method');
return 'Hello World!';
}
}
监控与维护
NestJS 应用程序可以通过多种工具进行监控和维护,如 PM2、Docker、Prometheus 等。PM2 是一个 Node.js 进程管理器,可以用来管理应用程序的启动、重启和更新。
示例代码
安装 PM2:
npm install pm2 -g
使用 PM2 启动应用程序:
pm2 start dist/main.js --name "MyNestApp"
使用 PM2 管理应用程序:
pm2 start ecosystem.config.js
在 ecosystem.config.js
文件中定义 PM2 配置:
module.exports = {
apps: [
{
name: 'MyNestApp',
script: 'dist/main.js',
watch: false,
env: {
NODE_ENV: 'production',
},
},
],
};
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章