Nest学习:新手入门全面指南
2024/11/15 6:03:05
本文主要是介绍Nest学习:新手入门全面指南,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Nest框架是一个基于Angular和Node.js的高效、模块化和可扩展的JavaScript框架,利用了TypeScript语言的强类型特性。它通过装饰器和依赖注入简化了复杂的业务逻辑实现,nest学习者可以通过本文了解其特点、安装方法和基本使用。文章还详细介绍了如何创建和测试简单的API接口,以及如何使用GraphQL增强API能力。
Nest框架是一个基于Angular和Node.js的高效、模块化和可扩展的JavaScript框架。它利用了TypeScript语言的强类型特性,为开发者提供了更好的代码结构和类型检查。Nest框架的设计理念是遵循面向对象编程的原则,通过使用装饰器和依赖注入来简化复杂的业务逻辑实现。
- 可扩展性:Nest框架的模块化设计使得你可以轻松地添加新的功能模块,而无需对现有代码进行大规模修改。
- 可维护性:清晰的模块划分和细致的代码结构使得代码易于理解和维护。
- 高效性:通过装饰器和依赖注入,Nest框架能够提供高效且简洁的代码实现。
- 可测试性:Nest框架支持单元测试和集成测试,使得软件的测试变得更加容易。
- 类型安全:利用TypeScript的强类型特性,Nest框架能够提供更好的类型检查,减少运行时错误。
安装Nest框架的第一步是确保你已经安装了Node.js和npm。接下来,使用npm全局安装Nest CLI,这是一个命令行工具,用于生成项目和管理项目文件。
npm install -g @nestjs/cli
安装完成后,可以使用nest new
命令来创建一个新的Nest项目:
nest new my-nest-app
上述命令会生成一个基础的Nest项目结构。你可以使用如下命令来启动项目:
npm run start
创建一个Nest项目的基本步骤如下:
- 安装Nest CLI。
- 使用
nest new
命令创建一个新的Nest项目。 - 启动项目并访问默认的API端点。
如上所述,安装Nest CLI后,可以使用以下命令创建一个新的Nest项目:
nest new my-nest-app
创建项目后,进入项目目录并启动项目:
cd my-nest-app npm run start
启动项目后,访问http://localhost:3000/api,可以看到默认的欢迎信息。
一个Nest项目通常包含以下主要文件和目录:
src/
:项目的源代码目录,包含模块、服务、控制器等。app.module.ts
:应用的主模块文件,定义了应用的基本结构。main.ts
:应用的启动文件,配置了应用的入口点。nest-cli.json
:Nest CLI配置文件。package.json
:项目的npm配置文件。README.md
:项目的说明文档。
app.module.ts
示例代码
app.module.ts
是项目的主模块文件,定义了应用的基本结构:
import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; @Module({ imports: [], controllers: [AppController], providers: [AppService], }) export class AppModule {}
main.ts
示例代码
main.ts
是应用的启动文件,配置了应用的入口点:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap();
创建一个简单的API接口通常涉及以下几个步骤:
- 创建控制器。
- 创建服务。
- 在控制器中使用服务。
创建控制器
控制器负责处理HTTP请求。创建一个简单的控制器:
nest generate controller user
生成的user.controller.ts
文件如下:
import { Controller, Get } from '@nestjs/common'; @Controller('users') export class UserController { @Get() findAll(): string { return 'All users'; } }
创建服务
服务是业务逻辑实现的载体。创建一个简单的服务:
nest generate service user
生成的user.service.ts
文件如下:
import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { getUsers(): string { return 'All users'; } }
在控制器中使用服务
修改控制器文件,使用服务来处理HTTP请求:
import { Controller, Get } from '@nestjs/common'; import { UserService } from '../user.service'; @Controller('users') export class UserController { constructor(private readonly userService: UserService) {} @Get() findAll(): string { return this.userService.getUsers(); } }
现在启动项目并访问http://localhost:3000/users
,可以看到返回的结果为All users
。
提供者是Nest框架中的服务或控制器。提供者使用@Injectable
装饰器标记,并通过@Module
装饰器的providers
数组来注册。提供者可以依赖注入其他提供者,从而实现模块化和解耦的代码结构。
示例代码
定义一个简单的提供者:
import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { getUsers(): string { return 'All users'; } }
控制器是Nest框架中处理HTTP请求的核心组件。每个控制器都包含一个或多个装饰器,用于定义HTTP方法(如@Get
)和路由路径。
示例代码
创建一个简单的控制器来处理HTTP GET请求:
import { Controller, Get } from '@nestjs/common'; @Controller('users') export class UserController { @Get() findAll(): string { return 'All users'; } }
服务是业务逻辑的实现载体。在Nest框架中,服务通常使用@Injectable
装饰器来标记。服务的作用是封装和组织应用的业务逻辑,使其更易于测试和维护。
示例代码
创建一个简单的服务来返回所有用户:
import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { getUsers(): string { return 'All users'; } }
模块是Nest框架中的核心概念之一。一个模块定义了一组控制器、服务和其他模块之间的依赖关系。模块通过@Module
装饰器来定义。
示例代码
定义一个简单的模块,包含一个控制器和一个服务:
import { Module } from '@nestjs/common'; import { UserController } from './user.controller'; import { UserService } from './user.service'; @Module({ controllers: [UserController], providers: [UserService], }) export class UserModule {}
在本章节中,我们将实现一个简单的用户注册和登录功能。首先,我们将创建一个注册接口,接收用户信息并将其存储在内存中。然后,我们将实现一个登录接口,验证用户信息并返回一个token。
创建用户模块
首先,我们需要创建一个用户模块来管理用户相关的服务和控制器。
nest generate module user
生成的user.module.ts
文件如下:
import { Module } from '@nestjs/common'; import { UserService } from './user.service'; import { UserController } from './user.controller'; @Module({ providers: [UserService], controllers: [UserController], }) export class UserModule {}
创建用户服务
接下来,我们需要创建一个用户服务,用于处理用户注册和登录逻辑。
nest generate service user
生成的user.service.ts
文件如下:
import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { private users = new Map<string, { username: string; password: string }>(); register(username: string, password: string): boolean { if (this.users.has(username)) { return false; } this.users.set(username, { username, password }); return true; } login(username: string, password: string): string | null { const user = this.users.get(username); if (!user) { return null; } if (user.password === password) { return 'token'; } return null; } }
创建用户控制器
现在,我们需要创建一个用户控制器来处理HTTP请求。
nest generate controller user
生成的user.controller.ts
文件如下:
import { Controller, Post, Body, Get } from '@nestjs/common'; import { UserService } from '../user.service'; @Controller('users') export class UserController { constructor(private readonly userService: UserService) {} @Post('register') register(@Body() body: { username: string; password: string }): string { const { username, password } = body; if (this.userService.register(username, password)) { return 'User registered successfully'; } return 'Username already exists'; } @Post('login') login(@Body() body: { username: string; password: string }): string | null { return this.userService.login(body.username, body.password); } }
测试注册和登录接口
启动项目并使用Postman测试注册和登录接口。
- 注册接口:
http://localhost:3000/users/register
- 登录接口:
http://localhost:3000/users/login
接下来,我们将实现一个简单的用户信息管理功能,包括获取用户列表和删除用户。
更新用户服务
首先,我们需要更新用户服务,添加获取用户列表和删除用户的方法。
import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { private users = new Map<string, { username: string; password: string }>(); register(username: string, password: string): boolean { if (this.users.has(username)) { return false; } this.users.set(username, { username, password }); return true; } login(username: string, password: string): string | null { const user = this.users.get(username); if (!user) { return null; } if (user.password === password) { return 'token'; } return null; } getUsers(): { username: string }[] { return Array.from(this.users.keys()).map((username) => ({ username })); } deleteUser(username: string): boolean { if (!this.users.has(username)) { return false; } this.users.delete(username); return true; } }
更新用户控制器
接下来,我们需要更新用户控制器,添加获取用户列表和删除用户的方法。
import { Controller, Post, Body, Get, Param } from '@nestjs/common'; import { UserService } from '../user.service'; @Controller('users') export class UserController { constructor(private readonly userService: UserService) {} @Post('register') register(@Body() body: { username: string; password: string }): string { const { username, password } = body; if (this.userService.register(username, password)) { return 'User registered successfully'; } return 'Username already exists'; } @Post('login') login(@Body() body: { username: string; password: string }): string | null { return this.userService.login(body.username, body.password); } @Get() getUsers(): { username: string }[] { return this.userService.getUsers(); } @Delete(':username') deleteUser(@Param('username') username: string): string { if (this.userService.deleteUser(username)) { return 'User deleted successfully'; } return 'User not found'; } }
测试用户信息管理接口
启动项目并使用Postman测试获取用户列表和删除用户接口。
- 获取用户列表接口:
http://localhost:3000/users
- 删除用户接口:
http://localhost:3000/users/{username}
接下来,我们将使用GraphQL增强API能力,实现一个简单的GraphQL接口来查询和操作用户信息。
安装Apollo库
首先,我们需要安装Apollo库来支持GraphQL。
npm install @nestjs/graphql @nestjs/apollo graphql
更新用户服务
接下来,我们需要更新用户服务,添加GraphQL查询和操作的方法。
import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { private users = new Map<string, { username: string; password: string }>(); register(username: string, password: string): boolean { if (this.users.has(username)) { return false; } this.users.set(username, { username, password }); return true; } login(username: string, password: string): string | null { const user = this.users.get(username); if (!user) { return null; } if (user.password === password) { return 'token'; } return null; } getUsers(): { username: string }[] { return Array.from(this.users.keys()).map((username) => ({ username })); } deleteUser(username: string): boolean { if (!this.users.has(username)) { return false; } this.users.delete(username); return true; } getUser(username: string): { username: string } | null { if (this.users.has(username)) { return { username }; } return null; } }
创建GraphQL模块
接下来,我们需要创建一个GraphQL模块来定义GraphQL类型和解析器。
nest generate module graphql
生成的graphql.module.ts
文件如下:
import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { UserResolver } from './user.resolver'; import { UserService } from '../user.service'; @Module({ imports: [ GraphQLModule.forRoot({ autoSchemaFile: true, }), ], providers: [UserResolver], }) export class GraphQLModule {}
创建GraphQL解析器
接下来,我们需要创建一个GraphQL解析器来实现GraphQL查询和操作。
nest generate resolver user
生成的user.resolver.ts
文件如下:
import { Resolver, Query, Args } from '@nestjs/graphql'; import { UserService } from '../user.service'; @Resolver() export class UserResolver { constructor(private readonly userService: UserService) {} @Query(() => String) register(@Args('username') username: string, @Args('password') password: string): string { if (this.userService.register(username, password)) { return 'User registered successfully'; } return 'Username already exists'; } @Query(() => String) login(@Args('username') username: string, @Args('password') password: string): string | null { return this.userService.login(username, password); } @Query(() => [String]) getUsers(): { username: string }[] { return this.userService.getUsers(); } @Query(() => String) getUser(@Args('username') username: string): { username: string } | null { return this.userService.getUser(username); } @Mutation(() => String) deleteUser(@Args('username') username: string): string { if (this.userService.deleteUser(username)) { return 'User deleted successfully'; } return 'User not found'; } }
测试GraphQL接口
启动项目并使用GraphQL Playground测试GraphQL接口。
- 注册用户:
mutation { register(username: "test", password: "test") }
- 登录用户:
mutation { login(username: "test", password: "test") }
- 获取用户列表:
query { getUsers }
- 获取用户信息:
query { getUser(username: "test") }
- 删除用户:
mutation { deleteUser(username: "test") }
Nest框架通过整合Jest和Supertest库提供了强大的单元测试和集成测试支持。下面是一个简单的测试示例,用于验证用户注册和登录功能是否正常工作。
单元测试示例
创建一个单元测试文件,用于测试用户服务中的注册和登录逻辑。
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 register a user', () => { const result = service.register('test', 'password'); expect(result).toBe(true); }); it('should not register a user twice', () => { service.register('test', 'password'); const result = service.register('test', 'password'); expect(result).toBe(false); }); it('should login a user', () => { service.register('test', 'password'); const token = service.login('test', 'password'); expect(token).toBe('token'); }); it('should not login a user with wrong password', () => { service.register('test', 'password'); const token = service.login('test', 'wrongPassword'); expect(token).toBeNull(); }); });
集成测试示例
创建一个集成测试文件,用于测试用户控制器中的注册和登录端点。
import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { UserController } from './user.controller'; import { UserService } from './user.service'; import { NestExpressApplication } from '@nestjs/platform-express'; import * as request from 'supertest'; describe('UserController', () => { let app: INestApplication; let userService: UserService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [UserController], providers: [UserService], }) .overrideProvider(UserService) .useClass(MockUserService) .compile(); app = module.createNestApplication<NestExpressApplication>(); userService = module.get<UserService>(UserService); await app.init(); }); afterAll(async () => { await app.close(); }); it('should register a user', () => { return request(app.getHttpServer()) .post('/users/register') .send({ username: 'test', password: 'password' }) .expect(200) .expect('User registered successfully'); }); it('should not register a user twice', () => { return request(app.getHttpServer()) .post('/users/register') .send({ username: 'test', password: 'password' }) .expect(200) .expect('User registered successfully') .then(() => { return request(app.getHttpServer()) .post('/users/register') .send({ username: 'test', password: 'password' }) .expect(200) .expect('Username already exists'); }); }); it('should login a user', () => { return request(app.getHttpServer()) .post('/users/login') .send({ username: 'test', password: 'password' }) .expect(200) .expect('token'); }); it('should not login a user with wrong password', () => { return request(app.getHttpServer()) .post('/users/login') .send({ username: 'test', password: 'wrongPassword' }) .expect(401); }); }); class MockUserService { register(username: string, password: string): boolean { return true; } login(username: string, password: string): string | null { if (username === 'test' && password === 'password') { return 'token'; } return null; } }
Docker是一个开源的容器化平台,可以用来创建和运行隔离的环境。下面是如何使用Docker进行环境隔离的示例。
创建Dockerfile
在项目的根目录下创建一个Dockerfile,用于构建Docker镜像。
cat > Dockerfile <<EOF FROM node:14 WORKDIR /app COPY package.json package-lock.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["npm", "run", "start"] EOF
构建Docker镜像
使用以下命令构建Docker镜像:
docker build -t my-nest-app .
运行Docker容器
使用以下命令运行Docker容器:
docker run -p 3000:3000 my-nest-app
创建一个docker-compose.yml
文件,用于管理Docker容器。
version: '3' services: app: build: . ports: - "3000:3000" environment: - PORT=3000 - DATABASE_URL=mongodb://localhost:27017/mydatabase
使用以下命令启动Docker容器:
docker-compose up
Nest框架提供了强大的错误处理功能,可以通过全局异常过滤器来捕获和处理异常。
全局异常过滤器示例
创建一个全局异常过滤器,用于捕获和处理异常。
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common'; @Catch() export class GlobalExceptionFilter implements ExceptionFilter { catch(exception: any, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse(); const request = ctx.getRequest(); const status = exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR; response.status = status; response.json({ statusCode: status, timestamp: new Date().toISOString(), path: request.url, message: exception.message, }); } }
注册全局异常过滤器
在app.module.ts
文件中注册全局异常过滤器。
import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { GlobalExceptionFilter } from './global.filter'; @Module({ imports: [], controllers: [AppController], providers: [AppService, { provide: APP_FILTER, useClass: GlobalExceptionFilter }], }) export class AppModule {}
在部署Nest应用之前,你需要构建项目并管理环境变量。
构建项目
使用以下命令构建项目:
npm run build
管理环境变量
创建一个.env
文件来管理环境变量。
cat > .env <<EOF PORT=3000 DATABASE_URL=mongodb://localhost:27017/mydatabase EOF
使用环境变量
在main.ts
文件中使用环境变量。
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import * as dotenv from 'dotenv'; dotenv.config(); async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(process.env.PORT); } bootstrap();
将Nest应用部署到云环境通常涉及以下几个步骤:
- 使用Docker容器化应用。
- 使用Docker Compose或Kubernetes管理应用。
- 使用云提供商的平台和服务部署应用。
使用Docker部署到云环境
使用Docker容器化应用,并使用Docker Compose或Kubernetes管理应用。
使用Docker Compose部署到云环境
创建一个docker-compose.yml
文件,用于管理Docker容器。
version: '3' services: app: build: . ports: - "3000:3000" environment: - PORT=3000 - DATABASE_URL=mongodb://localhost:27017/mydatabase
使用以下命令启动Docker容器:
docker-compose up
使用Kubernetes部署到云环境
创建一个deployment.yaml
和service.yaml
文件,用于管理Kubernetes资源。
# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-nest-app spec: replicas: 1 selector: matchLabels: app: my-nest-app template: metadata: labels: app: my-nest-app spec: containers: - name: my-nest-app image: my-nest-app ports: - containerPort: 3000 env: - name: PORT value: "3000" - name: DATABASE_URL value: "mongodb://localhost:27017/mydatabase"
# service.yaml apiVersion: v1 kind: Service metadata: name: my-nest-app spec: selector: app: my-nest-app ports: - protocol: TCP port: 80 targetPort: 3000
使用以下命令部署应用:
kubectl apply -f deployment.yaml kubectl apply -f service.yaml
日志管理和监控是应用部署后的重要环节,可以使用多种工具来实现。下面是如何使用Prometheus和Grafana进行监控和日志管理的示例。
使用Prometheus和Grafana进行监控
创建一个prometheus.yml
文件,用于配置Prometheus的监控。
global: scrape_interval: 15s scrape_configs: - job_name: 'nest-app' static_configs: - targets: ['localhost:3000']
创建一个grafana.json
文件,用于配置Grafana的监控。
{ "dashboard": { "id": -1, "title": "Nest App", "panels": [ { "type": "graph", "title": "Requests per second", "yAxes": [ { "label": "Requests/second", "format": "short" } ], "lines": true, "fill": 1, "nullPointMode": "connected", "xaxis": { "mode": "time" }, "yaxis": { "align": false, "alignLevel": null }, "targets": [ { "expr": "rate(nest_app_requests_total[5m])", "interval": "", "legendFormat": "Requests", "refId": "A" } ] } ] } }
使用Prometheus和Grafana进行监控的具体步骤可以参考Prometheus和Grafana的官方文档。
这篇关于Nest学习:新手入门全面指南的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-15JavaMailSender是什么,怎么使用?-icode9专业技术文章分享
- 2024-11-15JWT 用户校验学习:从入门到实践
- 2024-11-15RestfulAPI学习:新手入门指南
- 2024-11-15Server Component学习:入门教程与实践指南
- 2024-11-15动态路由入门:新手必读指南
- 2024-11-15JWT 用户校验入门:轻松掌握JWT认证基础
- 2024-11-15Nest后端开发入门指南
- 2024-11-15Nest后端开发入门教程
- 2024-11-15RestfulAPI入门:新手快速上手指南
- 2024-11-15Server Action入门:新手必读教程