为了账号安全,请及时绑定邮箱和手机立即绑定

Nest后端开发入门教程

标签:
PHP Java Python
概述

NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架,支持模块化架构、装饰器模式和依赖注入等特性。本文将详细介绍如何安装Node.js和Nest CLI,创建并配置第一个Nest项目。此外,文章还将深入探讨nest后端开发中的控制器与服务、数据库集成以及测试和调试技巧。

Nest框架简介
基本概念和特点

NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架。其主要特点包括:

  1. 模块化架构:NestJS 的核心理念是模块化,每个模块都是一个自包含的单元,可以独立开发和测试。
  2. 装饰器模式:NestJS 支持 TypeScript 装饰器,这使得代码更加简洁和可维护。
  3. 依赖注入:通过依赖注入,可以轻松地管理对象之间的依赖关系,提高代码的可测试性和可维护性。
  4. 可插拔中间件:类似 Express 的中间件机制,可以轻松地添加或移除中间件。
  5. 高性能:基于高性能的 Node.js 平台和框架设计,NestJS 旨在提供最佳的性能表现。
选择合适的数据库

NestJS 可以与多种数据库集成,常见的包括 MySQL、MongoDB 和 PostgreSQL。选择数据库时需要考虑具体需求,如数据量、查询性能和开发复杂度。本文以 MongoDB 为例进行介绍。

安装Node.js和Nest CLI

安装Node.js

  1. 访问 Node.js官网,下载并安装最新版本的 Node.js。

  2. 验证安装成功:
    node -v
    npm -v

安装Nest CLI

Nest CLI 是一个命令行工具,用于创建和管理 NestJS 项目。安装步骤如下:

  1. 安装 Nest CLI:

    npm install -g @nestjs/cli
  2. 验证安装成功:
    nest -v
创建第一个Nest项目
  1. 创建一个新的 Nest 项目:

    nest new my-nest-app
  2. 进入项目目录:

    cd my-nest-app
  3. 启动开发服务器:

    npm run start:dev
  4. 访问 http://localhost:3000,你应该能看到默认的 "Hello World!" 页面。
Nest项目结构和配置
项目目录结构详解

NestJS 的项目结构通常包含以下几个主要文件和目录:

  • src/:主要的源代码目录。
    • app.module.ts:应用的主模块文件。
    • app.controller.ts:应用的主控制器文件。
    • app.service.ts:应用的服务文件。
    • main.ts:应用的主入口文件。
  • package.json:项目配置文件,包含依赖、脚本等信息。
  • tsconfig.json:TypeScript 编译配置文件。
  • nest-cli.json:Nest CLI 配置文件。
创建控制器和路由

控制器用于处理 HTTP 请求并返回响应。控制器可以通过装饰器 @Controller() 定义。

创建控制器

nest generate controller app
  1. 创建控制器:

    // src/app.controller.ts
    import { Controller, Get, Post, Body } from '@nestjs/common';
    import { AppService } from './app.service';
    
    @Controller()
    export class AppController {
     constructor(private readonly appService: AppService) {}
    
     @Get()
     getHello(): string {
       return this.appService.getHello();
     }
    
     @Post('/create')
     create(@Body() body: any) {
       return this.appService.create(body);
     }
    }
  2. 创建服务:

    // src/app.service.ts
    export class AppService {
     getHello(): string {
       return 'Hello World!';
     }
    
     create(body: any) {
       return `Created: ${JSON.stringify(body)}`;
     }
    }
配置环境变量

环境变量在开发和生产环境中非常重要,用于区分不同的环境配置。NestJS 支持通过环境变量来配置不同环境的设置。

  1. 创建 .env 文件,用于存储环境变量:

    # .env
    PORT=3000
    DATABASE_URL=mongodb://localhost:27017/mydb
  2. src/app.module.ts 中使用环境变量:

    // src/app.module.ts
    import { Module } from '@nestjs/common';
    import { ConfigService } from '@nestjs/config';
    import { ConfigModule } from '@nestjs/config';
    
    @Module({
     imports: [
       ConfigModule.forRoot({
         envFilePath: '.env',
         isGlobal: true,
       }),
     ],
    })
    export class AppModule {}
  3. 在其他模块或服务中访问环境变量:

    import { Injectable } from '@nestjs/common';
    import { ConfigService } from '@nestjs/config';
    
    @Injectable()
    export class MyService {
     constructor(private readonly configService: ConfigService) {}
    
     getDatabaseUrl() {
       return this.configService.get<string>('DATABASE_URL');
     }
    }
安装和配置依赖库
  1. 安装依赖:

    npm install express @nestjs/microservices
  2. src/app.module.ts 中引入和配置:

    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { HttpModule } from '@nestjs/axios';
    import { MicroserviceOptions, Transport } from '@nestjs/microservices';
    
    @Module({
     imports: [
       HttpModule,
       // 配置微服务
       {
         name: 'UserModule',
         module: UserModule,
         useFactory: (configService: ConfigService) => ({
           transport: Transport.REDIS,
           options: {
             url: configService.get<string>('REDIS_URL'),
           },
         }),
         inject: [ConfigService],
       },
     ],
     controllers: [AppController],
     providers: [AppService],
    })
    export class AppModule {}
控制器与服务
创建控制器和路由

控制器用于处理 HTTP 请求并返回响应。控制器可以通过装饰器 @Controller() 定义。

创建控制器

nest generate controller user
  1. 创建控制器:

    // src/user.controller.ts
    import { Controller, Get, Post, Body } from '@nestjs/common';
    import { UserService } from './user.service';
    
    @Controller('users')
    export class UserController {
     constructor(private readonly userService: UserService) {}
    
     @Get()
     getUsers() {
       return this.userService.getAllUsers();
     }
    
     @Post()
     createUser(@Body() user: any) {
       return this.userService.createUser(user);
     }
    }
  2. 创建服务:

    // src/user.service.ts
    import { Injectable } from '@nestjs/common';
    
    @Injectable()
    export class UserService {
     private users = [];
    
     getAllUsers() {
       return this.users;
     }
    
     createUser(user: any) {
       this.users.push(user);
       return `User created: ${JSON.stringify(user)}`;
     }
    }
  3. 配置模块:

    // src/user.module.ts
    import { Module } from '@nestjs/common';
    import { UserController } from './user.controller';
    import { UserService } from './user.service';
    
    @Module({
     controllers: [UserController],
     providers: [UserService],
    })
    export class UserModule {}
编写简单的REST API

创建控制器方法

// src/user.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { UserService } from './user.service';

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  getUsers() {
    return this.userService.getAllUsers();
  }

  @Post()
  createUser(@Body() user: any) {
    return this.userService.createUser(user);
  }
}

创建服务方法

// src/user.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class UserService {
  private users = [];

  getAllUsers() {
    return this.users;
  }

  createUser(user: any) {
    this.users.push(user);
    return `User created: ${JSON.stringify(user)}`;
  }
}

配置模块

// src/user.module.ts
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';

@Module({
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}
服务的创建和使用

服务通常用于处理异步操作、数据访问以及其他业务逻辑。服务可以通过依赖注入的方式注入到控制器或其他服务中。

  1. 创建服务类:

    // src/user.service.ts
    import { Injectable } from '@nestjs/common';
    
    @Injectable()
    export class UserService {
     private users = [];
    
     getAllUsers() {
       return this.users;
     }
    
     createUser(user: any) {
       this.users.push(user);
       return `User created: ${JSON.stringify(user)}`;
     }
    
     updateUser(id: string, user: any) {
       return this.findUserById(id).then((u) => {
         u.name = user.name;
         u.email = user.email;
         return u;
       });
     }
    
     deleteUser(id: string) {
       return this.findUserById(id).then((u) => {
         const index = this.users.indexOf(u);
         if (index > -1) {
           this.users.splice(index, 1);
         }
         return true;
       });
     }
    
     findUserById(id: string) {
       return this.users.find((user) => user.id === id);
     }
    }
  2. 在控制器中使用服务:

    // src/user.controller.ts
    import { Controller, Get, Post, Body, Put, Param } from '@nestjs/common';
    import { UserService } from './user.service';
    
    @Controller('users')
    export class UserController {
     constructor(private readonly userService: UserService) {}
    
     @Get()
     getUsers() {
       return this.userService.getAllUsers();
     }
    
     @Post()
     createUser(@Body() user: any) {
       return this.userService.createUser(user);
     }
    
     @Put(':id')
     updateUser(@Param('id') id: string, @Body() user: any) {
       return this.userService.updateUser(id, user);
     }
    
     @Delete(':id')
     deleteUser(@Param('id') id: string) {
       return this.userService.deleteUser(id);
     }
    }
  3. 配置模块:

    // src/user.module.ts
    import { Module } from '@nestjs/common';
    import { UserController } from './user.controller';
    import { UserService } from './user.service';
    
    @Module({
     controllers: [UserController],
     providers: [UserService],
    })
    export class UserModule {}
数据库集成
选择合适的数据库

NestJS 可以与多种数据库集成,常见的包括 MySQL、MongoDB 和 PostgreSQL。选择数据库时需要考虑具体需求,如数据量、查询性能和开发复杂度。本文以 MongoDB 为例进行介绍。

连接数据库并集成到Nest项目
  1. 安装 MongoDB 客户端:

    npm install @nestjs/mongoose mongoose
  2. 配置 MongoDB 客户端:

    // src/app.module.ts
    import { Module } from '@nestjs/common';
    import { MongooseModule } from '@nestjs/mongoose';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    
    @Module({
     imports: [
       MongooseModule.forRoot(process.env.DATABASE_URL),
     ],
     controllers: [AppController],
     providers: [AppService],
    })
    export class AppModule {}
  3. 创建模型:

    // src/user.schema.ts
    import { Schema, Document } from 'mongoose';
    import { Prop, Schema as SchemaDecorator } from '@nestjs/mongoose';
    
    @SchemaDecorator()
    export class UserSchema extends Document {
     @Prop({ required: true })
     name: string;
    
     @Prop({ required: true })
     email: string;
    }
    
    export const UserSchemaName = 'User';
    export const UserSchemaObject = UserSchema;
    export const UserSchemaModelName = 'User';
  4. 创建服务:

    // src/user.service.ts
    import { Injectable } from '@nestjs/common';
    import { InjectModel } from '@nestjs/mongoose';
    import { UserSchema } from './user.schema';
    import { Model } from 'mongoose';
    
    @Injectable()
    export class UserService {
     constructor(@InjectModel(UserSchema.name) private userModel: Model<UserSchema>) {}
    
     async createUser(user: UserSchema) {
       return this.userModel.create(user);
     }
    
     async getAllUsers() {
       return this.userModel.find().exec();
     }
    
     async updateUser(id: string, user: UserSchema) {
       return this.userModel.findByIdAndUpdate(id, user, { new: true }).exec();
     }
    
     async deleteUser(id: string) {
       return this.userModel.findByIdAndRemove(id).exec();
     }
    }
实现基本的CRUD操作
  1. 创建控制器方法:

    // src/user.controller.ts
    import { Controller, Get, Post, Body, Put, Param } from '@nestjs/common';
    import { UserService } from './user.service';
    
    @Controller('users')
    export class UserController {
     constructor(private readonly userService: UserService) {}
    
     @Get()
     getAllUsers() {
       return this.userService.getAllUsers();
     }
    
     @Post()
     createUser(@Body() user: any) {
       return this.userService.createUser(user);
     }
    
     @Put(':id')
     updateUser(@Param('id') id: string, @Body() user: any) {
       return this.userService.updateUser(id, user);
     }
    
     @Delete(':id')
     deleteUser(@Param('id') id: string) {
       return this.userService.deleteUser(id);
     }
    }
  2. 更新用户信息:

    // src/user.service.ts
    async updateUser(id: string, user: UserSchema) {
     return this.userModel.findByIdAndUpdate(id, user, { new: true }).exec();
    }
  3. 删除用户:

    // src/user.service.ts
    async deleteUser(id: string) {
     return this.userModel.findByIdAndRemove(id).exec();
    }
  4. 在控制器中添加更新和删除方法:

    // src/user.controller.ts
    @Put(':id')
    updateUser(@Param('id') id: string, @Body() user: any) {
     return this.userService.updateUser(id, user);
    }
    
    @Delete(':id')
    deleteUser(@Param('id') id: string) {
     return this.userService.deleteUser(id);
    }
测试和调试
使用Jest进行单元测试

Jest 是一个流行的 JavaScript 测试框架,可以用来编写单元测试。

  1. 安装 Jest:

    npm install --save-dev jest @types/jest ts-jest
  2. jest.config.js 中配置 Jest:

    // jest.config.js
    module.exports = {
     preset: 'ts-jest',
     testEnvironment: 'node',
    };
  3. 创建测试文件:

    // src/user.service.spec.ts
    import { UserService } from './user.service';
    import { UserSchema } from './user.schema';
    
    describe('UserService', () => {
     let userService: UserService;
    
     beforeEach(() => {
       userService = new UserService();
     });
    
     it('should create user', async () => {
       const user = new UserSchema({
         name: 'John Doe',
         email: 'john.doe@example.com',
       });
       const result = await userService.createUser(user);
       expect(result).toBe('User created');
     });
    
     it('should get all users', async () => {
       const users = await userService.getAllUsers();
       expect(users.length).toBe(0);
     });
    });
  4. 运行测试:
    npm run test
使用Supertest进行集成测试

Supertest 是一个用于测试 HTTP API 的库。

  1. 安装 Supertest:

    npm install --save-dev supertest
  2. 创建集成测试文件:

    // src/user.controller.spec.ts
    import { Test, TestingModule } from '@nestjs/testing';
    import { INestApplication } from '@nestjs/common';
    import { UserController } from './user.controller';
    import { UserService } from './user.service';
    import { AppModule } from '../../app.module';
    import { request } from 'supertest';
    import { join } from 'path';
    
    describe('UserController (e2e)', () => {
     let app: INestApplication;
    
     beforeEach(async () => {
       const moduleFixture: TestingModule = await Test.createTestingModule({
         imports: [AppModule],
       }).compile();
    
       app = moduleFixture.createNestApplication();
       await app.init();
     });
    
     it('/users (GET)', () => {
       return request(app.getHttpServer())
         .get('/users')
         .expect(200)
         .expect([]);
     });
    
     it('/users (POST)', () => {
       return request(app.getHttpServer())
         .post('/users')
         .send({ name: 'John Doe', email: 'john.doe@example.com' })
         .expect(201)
         .expect('User created');
     });
    });
  3. 运行测试:
    npm run test
调试工具和技巧

调试是开发过程中不可或缺的一部分。NestJS 提供了一些内置的调试工具和技巧。

  1. 使用断点调试:

    // src/user.service.ts
    import { Injectable } from '@nestjs/common';
    import { InjectModel } from '@nestjs/mongoose';
    import { UserSchema } from './user.schema';
    import { Model } from 'mongoose';
    
    @Injectable()
    export class UserService {
     constructor(@InjectModel(UserSchema.name) private userModel: Model<UserSchema>) {}
    
     async createUser(user: UserSchema) {
       debugger;
       return this.userModel.create(user);
     }
    }
  2. 使用 console.log 打印调试信息:

    // src/user.service.ts
    @Injectable()
    export class UserService {
     async createUser(user: UserSchema) {
       console.log('Creating user:', user);
       return this.userModel.create(user);
     }
    }
  3. 使用环境变量区分调试和生产环境:

    // .env
    DEBUG=true
  4. 通过环境变量启用调试模式:

    // src/app.module.ts
    import { Module } from '@nestjs/common';
    import { ConfigService } from '@nestjs/config';
    import { ConfigModule } from '@nestjs/config';
    
    @Module({
     imports: [
       ConfigModule.forRoot({
         envFilePath: '.env',
         isGlobal: true,
       }),
     ],
    })
    export class AppModule {}
  5. 在主入口文件中启用调试模式:

    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import { ConfigService } from '@nestjs/config';
    
    async function bootstrap() {
     const app = await NestFactory.create(AppModule);
     const configService = app.get(ConfigService);
     if (configService.get<string>('DEBUG')) {
       app.enableShutdownHooks();
     }
     await app.listen(3000);
    }
    bootstrap();
部署和生产环境准备
打包和部署应用
  1. 打包应用:

    npm run build
  2. 使用 PM2 进行部署:
    npm install pm2 -g
    pm2 start dist/main.js --name my-nest-app
使用PM2管理应用

PM2 是一个进程管理器,可以帮助我们管理 Node.js 应用的生命周期。

  1. 安装 PM2:

    npm install pm2 -g
  2. 使用 PM2 启动应用:

    pm2 start dist/main.js --name my-nest-app
  3. 保存应用配置:

    pm2 save
  4. 重启应用:
    pm2 restart all
配置反向代理和SSL证书
  1. 获取 SSL 证书:
    可以使用 Let's Encrypt 提供的免费 SSL 证书。

    1. 安装 Certbot:

      sudo apt-get install certbot -y
    2. 生成 SSL 证书:
      sudo certbot --nginx -d example.com -d www.example.com
  2. 配置反向代理(使用 Nginx 为例):

    1. 安装 Nginx:

      sudo apt-get install nginx -y
    2. 编辑 Nginx 配置文件:

      server {
        listen 80;
        server_name example.com www.example.com;
      
        location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
        }
      }
      
      server {
        listen 443 ssl;
        server_name example.com www.example.com;
      
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
      
        location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
        }
      }
    3. 重启 Nginx:
      sudo systemctl restart nginx

通过以上步骤,你就可以成功部署和管理一个 NestJS 应用,并确保其在生产环境中运行良好。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消