目录

1.初始化 nest 项目

1.1 全局安装 nest cli

1.2 新建 nest-demo

1.3 启动 nest-demo

1.4 预览 nest-demo

2.添加 Module、Controller、Provider

2.1 创建 Module

2.2 创建 Controller

2.3 创建 Provider(service)

3.初始化数据库

3.1 启动 MongoDB 服务

3.2 引入 Mongoose 根模块

3.3 添加表的数据类型接口文件

4.在 nest 中操作数据库

4.1 在 User 模块中引入数据库

4.2 在 Provider 中添加数据库操作逻辑

4.3 在 Controller 中处理客户端请求

5.测试增删改查

5.1 新增用户信息

5.2 查询用户信息

5.3 更新用户信息


1.初始化 nest 项目

1.1 全局安装 nest cli

npm i -g @nestjs/cli

 

1.2 新建 nest-demo

nest new nest-demo

执行完成后,生成内容如下:

1.3 启动 nest-demo

yarn run start:dev

添加 :dev 的原因:方便 nest.js 监听本地文件的修改,实时重启服务

1.4 预览 nest-demo

在 main.ts 中,默认给出的项目运行端口号为 3000,因此可通过 localhost:3000 访问项目

 

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  
  /**
   * 监听端口
   * @description 可访问地址:http://localhost:3000/
   */
  await app.listen(3000);
}

bootstrap();

2.添加 Module、Controller、Provider

2.1 创建 Module

nest g module user server

执行后,会自动创建 user.module.ts,并在 app.module.ts 中自动引入 UserModule(在 根模块 中,引入 UserModule 模块)

user.module.ts 是 nest 模块文件,nest 使用 .module.ts(模块文件) 来组织应用结构

 

2.2 创建 Controller

nest g controller user server

执行后,会自动创建 user.controller.ts,并在 user.module.ts 中自动引入 UserController

Controller 的部分概念,类似于 “前端路由” 的概念

  • @Controller('user') 相当于根路由
  • @Get('users') 相当于嵌套路由

最终组成的路由:localhost:3000/user/users,这个路由可以获取全部用户信息 

综上所述,Controller 的作用:通过 “路由” 分发处理 请求和响应

import { Controller, Get } from '@nestjs/common';
 
@Controller('user')

export class UserController {
  /**
   * 返回用户全部信息
   */
  @Get('users')
  async findAll(): Promise<any> {
    return await this.xxx.xxx(); // 异步操作
  }
}

2.3 创建 Provider(service)

nest g service user server

执行后,会自动创建 user.service.ts,并在 user.module.ts 中自动引入 UserService

Provider(service)的作用是提供 Controller 需要的具体服务(比如数据库操作)

举个栗子:需要获取全部用户信息时,Controller 可以调用 Provider 暴露的方法,用于实现数据库操作、用户校验等复杂操作

3.初始化数据库

3.1 启动 MongoDB 服务

我按照一些教程下载了 MongoDB 之后,最初是能正常使用数据库的

但是下一次重启电脑就无法通过管理员身份的 cmd 启动 MongoDB 服务了,此处不想深究为什么

所以现在习惯于:直接在任务管理器中找到并启动 MongoDB 服务

如果不启动 MongoDB 服务,就无法在数据库可视化工具中连接数据库服务

数据库可视化界面

如果不启动 MongoDB 服务,nest 项目更是无法建立和数据库之前的连接的

3.2 引入 Mongoose 根模块

首先,需要在 nest 项目中,安装 MongoDB 的依赖 —— Mongoose

npm install mongoose @nestjs/mongoose --save

在 app.module.ts 中,引入 Mongoose 根模块

mongodb://localhost/localDataBaseName 指的是:在 nest 中操作的数据库,在电脑本地的地址

localDataBaseName 指的是:本地好多个数据库中的某个叫 localDataBaseName 的数据库

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './server/user/user.module';
/**
 * 引入 Mongoose 服务
 * @dependence npm install mongoose @nestjs/mongoose --save
 */
import { MongooseModule } from '@nestjs/mongoose';

// 连接数据库
const DBRootModule = MongooseModule.forRoot('mongodb://localhost/localDataBaseName');

@Module({
  imports: [DBRootModule, UserModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

 

3.3 添加表的数据类型接口文件

定义用户数据表的格式: user.schema.ts

import { Schema } from 'mongoose';
 
export const userSchema = new Schema({
  _id: { type: String, required: true },
  user_name: { type: String, required: true },
  password: { type: String, required: true }
});

定义单条用户数据的格式: user.interface.ts

import { Document } from 'mongoose';
 
export interface User extends Document {
  readonly _id: string;
  readonly user_name: string;
  readonly password: string;
}

定义 新建用户、编辑用户 需要的参数的数据类型接口: user.dto.ts

// 新建用户
export class CreateUserDTO {
  readonly _id: string;
  readonly user_name: string;
  readonly password: string;
}

// 编辑用户
export class EditUserDTO {
  readonly user_name: string;
  readonly password: string;
}

 

 

4.在 nest 中操作数据库

4.1 在 User 模块中引入数据库

import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
// 引入 Mongoose 模块
import { MongooseModule } from '@nestjs/mongoose';
// 引入用户数据表的格式
import { userSchema } from './user.schema';

const UserTable = MongooseModule.forFeature([{ name: 'Users', schema: userSchema }]);

@Module({
  imports: [UserTable],
  controllers: [UserController],
  providers: [UserService]
})
export class UserModule {}

 

4.2 在 Provider 中添加数据库操作逻辑

构造函数的作用:让 Provider(user.service)实例化时,能够接收并操作 User 数据库

mongoose 操作数据库是 异步 的,所以使用 async/await

/**
 * 新建 provider
 * @dependence nest g service user server
 */
import { Injectable } from '@nestjs/common';

// 为了在 user.service 中操作数据库
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';

// 引入数据类型
import { CreateUserDTO, EditUserDTO } from './user.dto';
import { User } from './user.interface';

@Injectable()
export class UserService {
  // 构造函数,让 user.service 在实例化时,能够接收到数据库 Model,进而操作数据库
  constructor(@InjectModel('Users') private readonly userModel: Model<User>) {}

  /**
   * mongoose 操作数据库是异步的,所以使用 async/await
   */
  
  // 查找所有用户
  async findAll(): Promise<User[]> {
    const users = await this.userModel.find();
    return users;
  }

  // 查找单个用户
  async findOne(_id: string): Promise<User> {
    return await this.userModel.findById(_id);
  }

  // 添加单个用户
  async addOne(body: CreateUserDTO): Promise<void> {
    await this.userModel.create(body);
  }

  // 编辑单个用户
  async editOne(_id: string, body: EditUserDTO): Promise<void> {
    await this.userModel.findByIdAndUpdate(_id, body);
  }

  // 删除单个用户
  async deleteOne(_id: string): Promise<void> {
    await this.userModel.findByIdAndDelete(_id);
  }
}

4.3 在 Controller 中处理客户端请求

此处就用到了在 4.2 里 Provider 定义的各种数据库操作方法服务

构造函数的作用:实例化 Proviver,使得 Controller 可以使用 Provider 提供的各种方法

/**
 * 新建 controller
 * @dependence nest g controller user server
 */
import {
  Controller,
  Body,
  Delete,
  Get,
  Param,
  Post,
  Put,
} from '@nestjs/common';
import { CreateUserDTO, EditUserDTO } from './user.dto';
import { User } from './user.interface';
import { UserService } from './user.service';

interface UserResponse<T = unknown> {
  code: number;
  data?: T;
  message: string;
}

@Controller('user')
export class UserController {
  // 实例化 provider
  constructor(private readonly userService: UserService) {}

  // GET /user/users
  @Get('users')
  async findAll(): Promise<UserResponse<User[]>> {
    return {
      code: 200,
      data: await this.userService.findAll(),
      message: 'Success.',
    };
  }

  // GET /user/:_id
  @Get(':_id')
  async findOne(@Param('_id') _id: string): Promise<UserResponse<User>> {
    return {
      code: 200,
      data: await this.userService.findOne(_id),
      message: 'Success.',
    };
  }

  // POST /user
  @Post()
  async addOne(@Body() body: CreateUserDTO): Promise<UserResponse> {
    await this.userService.addOne(body);
    return {
      code: 200,
      message: 'Success.',
    };
  }

  // PUT /user/:_id
  @Put(':_id')
  async editOne(
    @Param('_id') _id: string,
    @Body() body: EditUserDTO,
  ): Promise<UserResponse> {
    await this.userService.editOne(_id, body);
    return {
      code: 200,
      message: 'Success.',
    };
  }

  // DELETE /user/:_id
  @Delete(':_id')
  async deleteOne(@Param('_id') _id: string): Promise<UserResponse> {
    await this.userService.deleteOne(_id);
    return {
      code: 200,
      message: 'Success.',
    };
  }
}

5.测试增删改查

5.1 新增用户信息

5.2 查询用户信息

最开始没注意使用了 post,但是 nest 中要求的是 get,所以会出现如下问题

切换为 get 请求后,就能正常接收到响应了

 

5.3 更新用户信息

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐