保姆级入门nest笔记

news2024/11/16 5:24:06

使用 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']);
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/78589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pixracer接线图 及电调调参 BLheliSuite

Pixracer接线指南 pixracer官方链接 正反面引脚定义 接口含义 BLheliSuite调参软件 官方下载&#xff1a; https://www.mediafire.com/folder/dx6kfaasyo24l/BLHeliSuite 我使用了如下软件https://www.mediafire.com/file/9uccf1zy3wqb1w5/BLHeliSuite32_32.9.0.3.zip/fil…

Bio-Net:编解码器结构的循环双向连接网络

目录 摘要 方法 循环双向跳跃连接 前向跳跃连接 后向跳跃连接 递归的推断训练 BiO-Net网络结构 总结 摘要 对UNet以前的扩展主要集中对现有模块的改进或者提出新的模块来提高性能。因此这些变量通常会导致模型的复杂性不可忽视的增加。为了解决这种复杂性的问题。在本…

redis cluster 集群安装

redis cluster 集群安装 redis集群方案 哨兵集群 如图&#xff0c;实际上还是一个节点对外提供服务&#xff0c;所以虽然是三台机器&#xff0c;但是还是一台机器的并发量&#xff0c;而且master挂了之后&#xff0c;整个集群不能对外提供服务 cluster集群 多个主从集群节点…

五、伊森商城 前端基础-Vue 整合ElementUI快速开发 p28

目录 一、安装 1、安装ElementUI 2、在main.js文件中引入 2.1、引入ElementUI组件 2.2、让Vue使用ElementUI组件 二、使用 1、在hello.vue组件使用单选框 2、使用ElementUI快速搭建后台管理系统 2.1、修改App.vue 3、修改功能成动态显示 3.1、编写快速生成组件的模板 3…

java计算机毕业设计ssm学习互助平台网站8f554(附源码、数据库)

java计算机毕业设计ssm学习互助平台网站8f554&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff0…

C++11之引用

文章目录目的为啥要引入右值引用什么是右值引用右值引用作用移动构造函数移动语义 std::move移动语义注意事项完美转发博客目的 了解对应左值引用&#xff0c; 右值引用&#xff0c;移动语义&#xff0c; 完美转发含义。 右值引用&#xff08;及其支持的移动语义Move semanti…

1562_AURIX_TC275_电源监控

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 这一次的学习笔记内容比较少&#xff0c;因为有几页的文档内容跟之前看过的DataSheet内容雷同。因此&#xff0c;相应的学习笔记不再整理。 之前的学习笔记&#xff1a; (56条消息) 1451_…

Python学习基础笔记四十——os模块

os模块是与操作系统交互的一个接口。 os的方法Linux命令备注os.getcwd()pwd获取当前工作目录路径os.chdir()cd切换当前工作目录os.makedirs(dirname1/dirname2)mkdir -p dirname1/dirname2生成多级目录os.removedirs(dirname1)rmdir删除多级目录os.mkdir(dirname)mkdir dirnam…

JAVA入门零基础小白教程day04-数组

day04_java基础 课程目标 1. 【掌握】 IDEA的基本使用 2. 【理解】 什么是数组 3. 【掌握】 数组的定义及初始化 4. 【理解】 数组的内存图 6. 【理解】 数组常见的问题 7. 【掌握】 数组的案例 8. 【理解】 二维数组开发工具 一维数组 什么是数组 数组就是存储数据长度固定…

【Linux】源码安装Apache、Mysql、PHP以及LAMP部署验证

文章目录源码安装相关理论源代码安装特点源码包安装步骤一、源码安装Apache1、编译安装依赖包 apr2、编译安装依赖包 apr-util3、编译安装依赖包 pcre4、编译安装 Apache5、重启 apache 服务6、修改网页显示内容7、访问测试二、源码安装Mysql1、把系统自带的 boost 库卸载&…

【mmdetection系列】mmdetection之loss讲解

目录 1.configs 2.具体实现 3.调用 3.1 注册 3.2 调用 配置部分在configs/_base_/models目录下&#xff0c;具体实现在mmdet/models/loss目录下。 1.configs 有的时候写在head中作为参数&#xff0c;有的时候head内部进行默认调用。 我们以为例&#xff08;这里没有直接…

linux timer浅析

linux timer 1、数据结构 1.1 timer_list struct timer_list {struct hlist_node entry;unsigned long expires;void (*function)(struct timer_list *);u32 flags;#ifdef CONFIG_LOCKDEPstruct lockdep_map lockdep_map; #endif };entry:定时器保存到哈希表中的节点&am…

QT+Python停车场车牌识别计费管理系统

程序示例精选 Python停车场车牌识别计费管理系统 如需安装运行环境或远程调试&#xff0c;见文章底部微信名片&#xff01; 前言 QTPython是非常经典的窗体编程组合&#xff0c;功能完善&#xff0c;可视化界面美观易维护&#xff0c;这篇博客针对停车场车牌识别计费方面编写代…

JavaScript前端实用的工具函数封装

这篇文章主要为大家介绍了JavaScript前端实用的一些工具函数的封装&#xff0c;有需要的朋友可以借鉴参考下&#xff0c;希望能够有所帮助! 1.webpack里面配置自动注册组件 第一个参数是匹配路径,第二个是深度匹配,第三个是匹配规则 const requireComponent require.contex…

20-Django REST framework-Serializer序列化器

Serializer序列化器前言序列化器作用定义Serializer定义方法字段与选项创建Serializer对象序列化使用基本使用增加额外字段关联对象序列化反序列使用模型类序列化器ModelSerializer指定字段前言 本篇来学习Serializer序列化器知识 序列化器作用 进行数据的校验对数据对象进行…

[附源码]计算机毕业设计基于VUE的网上订餐系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【代码审计-JAVA】基于javaweb框架开发的

目录 一、javaweb三大框架 1、Spring&#xff08;开源分层的框架&#xff09; 2、Struts&#xff08;MVC设计模式&#xff09; 3、Hibernate&#xff08;开源的对象关系映射框架&#xff09; 二、特征 1、结构 2、Servlet 三、重要文件 1、web.xml 2、pom.xml 3、web…

【文献研究】班轮联盟下合作博弈的概念

前言&#xff1a;以下是本人做学术研究时搜集整理的资料&#xff0c;供有相同研究需求的人员参考。 1. 合作博弈的一些概念 合作博弃中比较重要的问题是共赢状态下的利润分配问题&#xff0c;这关系到联盟的合作机制能否长期有效。这里首先介绍几个重要的概念&#xff1a; &…

174.Django中文件上传和下载

1. 文件上传和下载环境搭建 创建django项目和子应用urls中包含子应用&#xff0c;在子应用中创建urls.py配置数据库sqlite3&#xff08;默认就是&#xff0c;无需配置&#xff09;配置settings&#xff0c;上传文件目录编写模型代码&#xff08;下面给出&#xff09;模型的预迁…

如何使用Java获取货币符号?

1. 前言 最近做了一个支付相关的需求&#xff0c;要求在收银台页面显示商品的价格时带上货币符号&#xffe5;&#xff0c;类似下图中的格式&#xff1a; 最初我是用的下面这样的代码&#xff1a; System.out.println(Currency.getInstance(Locale.CHINA).getSymbol());本机测…