保姆级入门nest笔记

Posted усил

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了保姆级入门nest笔记相关的知识,希望对你有一定的参考价值。

使用 NEXT 搭建后台服务接口

https://docs.nestjs.com/

# 准备工作

  • 安装 node

  • 全局安装 nest

    • npm i -给@nestjs/cli

    • nest --version


# 创建项目

  • 创建项目next new

  • 启动项目npm run startnpm run start:dev

  • 访问接口 localhost:3000

  • 获取命令解释 next g -h


# 快速创建 RESTAPI 入口文件

  • 进入项目根目录下,执行命令 nest g res books --no-spec

注意:–no-spec 不生成单元测试文件

也可以进行全局配置

nest-cli.json 添加以下代码即可

"generateOptions": 
    "spec": false
 


# 配置生成接口文档

  • npm install --save @nestjs/swagger

修改项目 main.ts 配置文件增加以下代码

import  NestFactory  from '@nestjs/core';
import  SwaggerModule, DocumentBuilder  from '@nestjs/swagger';
import  AppModule  from './app.module';

async function bootstrap() 
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('接口文档')
    .setDescription('这个接口文档我是自动生成的')
    .setVersion('1.0')
    .addTag('blog')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);

bootstrap();
  • 启动项目

  • 进行接口测试


# 设置请求方式及其获取参数

// books.controller.ts
import 
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
 from '@nestjs/common';
import  BooksService  from './books.service';
import  CreateBookDto  from './dto/create-book.dto';
import  UpdateBookDto  from './dto/update-book.dto';

@Controller('books')
export class BooksController 
  constructor(private readonly booksService: BooksService) 

  @Post()
  create(@Body() createBookDto: CreateBookDto) 
    // 创建 book 数据
    return this.booksService.create(createBookDto);
  

  @Get('/findAll')
  findAll() 
    // 获取所有 book 数据
    return this.booksService.findAll();
  

  @Get(':id')
  findOne(@Param('id') id: string) 
    // 查找指定 id 的 book
    return this.booksService.findOne(id);
  

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateBookDto: UpdateBookDto) 
    // 更新指定 id 的 book
    return this.booksService.update(id, updateBookDto);
  

  @Delete(':id')
  remove(@Param('id') id: string) 
    // 删除指定 id 的 book
    return this.booksService.remove(id);
  


# 对接数据库

使用 prisma 对接数据库

步骤一:安装 prisma npm install prisma --save-dev

步骤二:初始化 prisma npx prisma init

在 vsCode 中打开 schema.prisma 需要下载 prisma 插件

步骤三:在 schema.prisma 初始化数据表

generator client 
  provider = "prisma-client-js"


datasource db 
  provider = "sqlite"
  url      = env("DATABASE_URL")


// 用户表
model user 
  // id 为主键
  id String @id @unique @default(uuid())
  userName String @unique @map("user_name")
  // 默认值为 ""  
  password String @default("")
  nickName String @default("") @map("nick_name")
  createdAt DateTime @default(now()) @map("created_at")
  updateAt DateTime @updatedAt @map("updated_at")

  @@map("users") // 给表其别名


// 书籍表
model book 
  id String @id @unique @default(uuid())
  title String @default("")
  author String @default("")
  price Float @default(0)

  @@map("books")

步骤四:生成数据库npx prisma db push

步骤五:创建 prisma 的服务

npx prisma init --datasource-provider sqlite

会在 src 目录下生成 prisma 文件

并且在要使用数据库连接的RESTAPI模块中进行注册

// books.module.ts
import  Module  from '@nestjs/common';
import  BooksService  from './books.service';
import  BooksController  from './books.controller';
import  PrismaService  from 'src/prisma/prisma.service';

@Module(
  controllers: [BooksController],
  providers: [BooksService, PrismaService],
)
export class BooksModule 

步骤六:在 vscode 中打开数据库

(1)在 vscode 中 下载 sqlite

(2) 打开命令面板(Ctrl + Shift + P)

此时在 vscode 的左侧可以看到数据库中的两张表

使用prisma对数据进行增删查改

// books.service.ts
import  Injectable  from '@nestjs/common';
import  CreateBookDto  from './dto/create-book.dto';
import  UpdateBookDto  from './dto/update-book.dto';
import  PrismaService  from 'src/prisma/prisma.service';
@Injectable()
export class BooksService 
  // 创建 只读 的 prismaService 实体类  
  constructor(private readonly prismaService: PrismaService) 
  
  // 创建 book 数据
  create(createBookDto: CreateBookDto) 
    return this.prismaService.book.create(
      data: createBookDto,
    );
  
    
  // 获取所有 book 数据
  findAll() 
    return this.prismaService.book.findMany( where:  );
  
    
  // 查找指定 id 的 book
  findOne(id: string) 
    return this.prismaService.book.findUnique(
      where: 
        id,
      ,
    );
  
  
  // 更新指定 id 的 book  
  update(id: string, updateBookDto: UpdateBookDto) 
    return this.prismaService.book.update(
      where: 
        id,
      ,
      data: updateBookDto,
    );
  
  
  // 删除指定 id 的 book  
  remove(id: string) 
    return this.prismaService.book.delete(
      where: 
        id,
      ,
    );
  

create-book.dto 与 update-book.dto 解释

这两个文件都是用于存放 book 在 创建数据 以及 更新数据 时,数据的类型。

类似于 Java 中的实体类

好处在于:可以更好的对数据进行管理,并且当用户传入不合法的数据结构时, nest 可以对此做出处理,后面会具体涉及

// create-book.dto
export class CreateBookDto 
  title: string;
  author: string;
  price: number;


# 对数据格式进行处理

这里使用第一种方式: npm i --save class-validator class-transformer,并在 main.ts 进行注册

import  ValidationPipe  from '@nestjs/common';
async function bootstrap() 
    const app = await NestFactory.create(AppModule);
    app.useGlobalPipes(new ValidationPipe());
    await app.listen(3000);

bootstrap();

回到 create-book.dto

import  ApiProperty  from '@nestjs/swagger';
import  IsNotEmpty, IsString  from 'class-validator';

export class CreateBookDto 
  @ApiProperty(
    name: 'title',
    description: '书名',
  )   
  @IsNotEmpty( message: '书名不能为空' )
  title: string;

  @ApiProperty(
    name: 'author',
    description: '作者',
  )
  @IsString( message: '必须为字符串' )  
  author: string;

  @ApiProperty(
    name: 'price',
    description: '价格',
  )
  price: number;

补充: @ApiProperty 是在生成接口文档对实体类中的每个字段进行描述


# 统一返回数据格式

  • nest g itc all-response --no-spec

同样需要在 main.ts 进行注册

import  AllResponseInterceptor  from './all-response.interceptor';
async function bootstrap() 
    const app = await NestFactory.create(AppModule);
    app.useGlobalInterceptors(new AllResponseInterceptor());
    await app.listen(3000);

bootstrap();

接着在 all-response.interceptor 对数据进行格式处理

import 
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
 from '@nestjs/common';
import  Observable, map  from 'rxjs';

@Injectable()
export class AllResponseInterceptor implements NestInterceptor 
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> 
    return next.handle().pipe(
      map((data) => 
        return 
          data,
          success: true,
          errorMessage: '',
        ;
      ),
    );
  


# 异常处理

  • nest g f any-exception --no-spec

同样需要在 main.ts 进行注册

import  AnyExceptionFilter  from './any-exception.filter';
async function bootstrap() 
    const app = await NestFactory.create(AppModule);
     app.useGlobalFilters(new AnyExceptionFilter());
    await app.listen(3000);

bootstrap();

接着在 any-exception.filter 对异常进行处理

import 
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
 from '@nestjs/common';

@Catch()
export class AnyExceptionFilter<T> 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).json(
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      // errorMessage: exception?.message,
      data: ,
      success: false,
    );
  


# 中间键

  • nest g mi validate-login --no-spec

  • npm i cookie-parser

// validate-login.middleware
import 
  Injectable,
  NestMiddleware,
  UnauthorizedException,
 from '@nestjs/common';

@Injectable()
export class ValidateLoginMiddleware implements NestMiddleware 
  use(req: any, res: any, next: () => void) 
    if (req.cookies.token) 
      next();
     else 
      throw new UnauthorizedException();
    
    next();
  

在 App.module.ts 进行拦截注册

import  ValidateLoginMiddleware  from './validate-login.middleware';
export class AppModule implements NestModule 
  configure(consumer: MiddlewareConsumer) 
    consumer.apply(ValidateLoginMiddleware).forRoutes(...['move']);
  

以上是关于保姆级入门nest笔记的主要内容,如果未能解决你的问题,请参考以下文章

保姆级尚硅谷SpringCloud学习笔记(更新中)

保姆级 tomcat 快速入门

Maix Bit(K210)保姆级入门上手教程---环境搭建

XML快速入门的保姆级教程!!!

PyQt5保姆级教程-- 从入门到精通

保姆级!!前端必会Taro入门级教学!!