nestJs笔记2
一 swagger文档
安装
yarn add @nestjs/swagger
引入
import {DocumentBuilder, SwaggerModule} from '@nestjs/swagger'
配置 main.ts
// 设置swagger文档相关配置
const swaggerOptions = new DocumentBuilder()
.setTitle('nest api document') //文档名
.setDescription('nest api des') //文档描述
.setVersion('1.0') //版本
.addBearerAuth() //鉴权
.build()
// 创建文档
const document = SwaggerModule.createDocument(app, swaggerOptions)
SwaggerModule.setup('doc', app, document) //访问路径, 应用于, 文档
访问
localhost:3000/doc
nest集成swagger_大神乔伊的博客-CSDN博客_nest swagger
@ApiTags('user') 设置模块接口的分类,不设置默认分配到default
@ApiOperation({ summary: '标题', description: '详细描述'}) 单个接口描述
传参
@ApiQuery({ name: 'limit', required: true}) query参数
@ApiQuery({ name: 'role', enum: UserRole }) query参数
@ApiParam({ name: 'id' }) parma参数
@ApiBody({ type: UserCreateDTO, description: '输入用户名和密码' }) 请求体
响应
@ApiResponse({
status: 200,
description: '成功返回200,失败返回400',
type: UserCreateDTO,
})
验证
@ApiProperty({ example: 'Kitty', description: 'The name of the Cat' })
name: string;
二 middleware logger
生成一个中间件
nest g middleware common/middleware/logging
在中间件函数内部进行操作
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from 'express'
@Injectable()
export class LoggingMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => void) {
// 我们在中间件函数内部可以拿到请求和响应的内容,根据这些内容可以做一些中间件操作
// 默认req和res是any类型,需要引入express中的request和response
console.log(req.method, req.params);
next();
}
}
应用中间件到路由
在module文件中,配置中间件的应用
import { MiddlewareConsumer, Module, NestMiddleware, RequestMethod } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ArticalController } from './artical/artical.controller';
import { UsersController } from './users/users.controller';
import { EjsEngineController } from './ejs_engine/ejs_engine.controller';
import { NewsService } from './news/news.service';
import { NewsController } from './news/news.controller';
import { LoggingMiddleware } from './common/middleware/logging.middleware';
@Module({
imports: [],
// 在module中注册controller 和 providers
controllers: [AppController, ArticalController, UsersController, EjsEngineController, NewsController],
providers: [AppService, NewsService],
})
export class AppModule{
// 配置middleware,将LoggingMiddleware应用于指定范围内的路由
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggingMiddleware) //制定应用的中间件
.exclude({path:'news', method:RequestMethod.POST}) //不应用于news路径下和POST请求的路由
.forRoutes('*')
}
}
三 异常处理
四 管道
管道用于转换参数类型
在方法参数装饰器内调用类(局部管道)
转换前
@Get('getUserBy')
getUserBy(@Query('id') id): String {
console.log(id); //123
console.log(typeof(id)); //String
return '获取用户'
}
转换后
@Get('getUserBy')
getUserBy(@Query('id', new ParseIntPipe()) id:number): String {
console.log(id); //123
console.log(typeof(id)); //number
return '获取用户'
}
创建管道pipe
nest g pipe pipes/parse-int
五 守卫
守卫在中间件之后执行,但是在管道和拦截器之前执行
创建守卫
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
// guard内必须要有一个函数canActive
canActivate(
context: ExecutionContext, // canActive内唯一参数context是ExecutionContext实例
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
console.log('request',request)
return true;
}
}
使用守卫
// 全局使用守卫
app.useGlobalGuards(new RoleGuardGuard())
// 局部使用守卫(作为装饰器使用)
import { Body, Controller, Get, Param, ParseIntPipe, Post, Query, Request, UseGuards } from '@nestjs/common';
import { ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { AuthGuard } from 'src/common/guard/role-guard.guard';
@UseGuards(AuthGuard) //请求use下接口会被gaurd调用
@Controller('users')
@ApiTags('user')
export class UsersController {
@Get()
index(): String{
return '用户中心'
}
}
六 数据库连接
可以直接使用任何通用的nodejs数据库集成库或
ORM例如 Sequelize (recipe)、knexjs (tutorial)`和 TypeORM ,以在更高的抽象级别上进行操作。
这里使用
Sequelize来对数据库操作,相较于官网推荐的TypeORM更加稳定,npm下载量也更高
安装
安装数据库驱动程序和sequelize
yarn add @nestjs/sequelize sequelize sequelize-typescript mysql2
安装对ts的支持
yarn add @types/sequelize --dev
步骤:
1 导入sequelize模块 app.module.ts
import { MiddlewareConsumer, Module, NestMiddleware, RequestMethod } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ArticalController } from './artical/artical.controller';
import { UsersController } from './users/users.controller';
import { EjsEngineController } from './ejs_engine/ejs_engine.controller';
import { NewsService } from './news/news.service';
import { NewsController } from './news/news.controller';
import { LoggingMiddleware } from './common/middleware/logging.middleware';
import { SequelizeModule } from '@nestjs/sequelize';
import { SongListModule } from './song_list/song_list.module';
import { Song_list } from './song_list/song_list.model';
@Module({
imports: [
// 配置连接数据库信息
SequelizeModule.forRoot({
dialect: 'mysql',
host: 'localhost',
port: 3309,
username: 'root',
password: '123456',
database: 'graduation_project',
models: [Song_list], //引入表格模型
}),
SongListModule
],
// 在module中注册controller 和 providers
controllers: [AppController, ArticalController, UsersController, EjsEngineController, NewsController],
providers: [AppService, NewsService],
})
export class AppModule{
// 配置middleware,将LoggingMiddleware应用于指定范围内的路由
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggingMiddleware)
.exclude({path:'news', method:RequestMethod.POST}) //不应用于news路径下和POST请求的路由
.forRoutes('*')
}
}
2 注入Sequelize到项目中 app.service.ts
import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';
@Injectable()
export class AppService {
// 注入Sequelize到项目中
constructor(private sequelize: Sequelize) { }
getHello(): string {
return 'nihao1 nestjs';
}
getp(): String {
return 'product'
}
}
3 定义一个模型 song_list.model.ts
// 在model文件内创建表格模型 可以通过@Column({defaultValue: true})
import { Table, Column, Model } from "sequelize-typescript";
@Table
export class Song_list extends Model<Song_list>{
@Column({primaryKey: true})
id: number
@Column
listname: String
@Column
collect: number
@Column
share: number
@Column
comment: number
}
4 要开始使用模型,我们需要通过将其插入到
forRoot()方法选项的models数组中来让Sequelize知道它的存在。
//app.modules.ts
imports: [
// 配置连接数据库信息
SequelizeModule.forRoot({
dialect: 'mysql',
host: 'localhost',
port: 3309,
username: 'root',
password: '123456',
database: 'graduation_project',
models: [Song_list], //引入表格模型
//配置防止报错
define: {
freezeTableName: true, //配置不在表名后面加s
timestamps: false //配置不加createdAt和updateAt字段
}
}),
SongListModule //导入模块
],
5 在service内注入表格模型,对该表进行增删改查功能 song_list.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { Song_list } from './song_list.model';
@Injectable()
export class SongListService {
constructor(
//使用@InjectModel()装饰器来把UserModel注入到UsersService中。
@InjectModel(Song_list)
private songListModel: typeof Song_list
) { }
//查找所有数据
async findAll(): Promise<Song_list[]> {
return this.songListModel.findAll();
}
}
6 使用service内的功能,开放数据接口 song_list.controller.ts
import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { SongListService } from './song_list.service';
@Controller('songlist')
@ApiTags('songlist')
export class SongListController {
constructor(private SongListService: SongListService) { }
@Get('allsong')
getAllSong() {
return this.SongListService.findAll()
}
@Get()
getData() {
return 'song list print msg'
}
}
7 将模块注册导出 song_list.module.ts
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { Song_list } from './song_list.model';
import { SongListController } from './song_list.controller';
import { SongListService } from './song_list.service';
@Module({
imports: [SequelizeModule.forFeature([Song_list])],//定义songListModule模块被注册到当前范围内
controllers: [SongListController],
providers: [SongListService],
exports: [SequelizeModule] //导出Sequelize
})
export class SongListModule {}
七 jwt验证登录
本地passport策略
yarn add @nestjs/passport passport passport-local
yarn add @types/passport-local -D
安装依赖
yarn add @nestjs/jwt passport-jwt
yarn add @types/passport-jwt -D