完善接口
在上一篇中定义初步接口的增删改查,这篇我们接着完善接口数据。
定义 DTO
DTO 全程 Data Transfer Object 即数据传输对象,在文章模块中定义 CreatePostDto
来约束数据
TS
class CreatePostDto {
@ApiProperty({
description: '文章标题',
example: '标题',
})
title: string;
@ApiProperty({ description: '文章内容', example: '内容' })
content: string;
}
可以对属性进行描述,在接口中直接定义
TS
@Post()
@ApiOperation({
summary: '创建文章',
})
async create(@Body() createPostDto: CreatePostDto) {
const data = await PostModel.create(createPostDto);
return {
success: 0,
data,
};
}
在接口中看到存在 @Body
装饰器,这是获取 body 数据,其中还存在 @Query
、@Param
装饰器,看定义我们大概能知道其中的含义:
- Body :获取 body 数据
- Query:获取 query 数据
- Param:获取 param
对应到接口上
TS
export class PostsController {
@Get()
@ApiOperation({
summary: '获取文章列表数据',
})
findAll() {
return [
{
id: 1,
title: '标题'
}
];
}
@Post()
@ApiOperation({
summary: '创建文章',
})
create(@Body() createPostDto: CreatePostDto) {
return {
success: 0,
};
}
@Get(':id')
@ApiOperation({
summary: '获取文章详情',
})
async detail(@Param('id') id: string) {
return {
success: 0,
};
}
@Put(':id')
@ApiOperation({
summary: '编辑文章',
})
update(
@Param('id') id: string,
@Body() createPostDto: CreatePostDto
) {
return {
success: 0,
};
}
@Delete(':id')
@ApiOperation({
summary: '删除文章',
})
remove(@Param('id') id: string) {
return {
success: 0,
};
}
}
连接数据库
接口我们都定义好后,可以连接数据库实现基础逻辑。这里使用 mongoose
数据库。在使用前需要安装依赖:
npm i @typegoose/typegoose mongoose @types/mongoose --save
注意:这里默认已安装 mongodb 数据库,未安装数据库请自行安装
在入口文件 main.ts
文件中连接数据库
TS
import * as mongoose from 'mongoose';
async function bootstrap() {
mongoose.connect('mongodb://localhost/nestjs-test-api', {}, (err: any) => {
if (err) {
console.log(err, '数据库连接错误!');
}
console.log('数据库连接成功!');
});
...
}
bootstrap();
定义 Model
数据库连接成功后,接下来需要定义数据 Model
,在 Posts
定义 post.model.ts
文件。
TS
import { getModelForClass, prop } from '@typegoose/typegoose';
export class Post {
@prop()
title: string
@prop()
content: string
}
export const PostModel = getModelForClass(Post);
注意: model 定义推荐单数 post 定义
定义数据模型后,可以直接在控制器中使用,由于 TS 特性,完全可以自动识别到 mongodb
方法;可以简单的实现文章接口的增删改查
TS
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
Query,
} from '@nestjs/common';
import { ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';
import { PostModel } from './post.model';
class CreatePostDto {
@ApiProperty({
description: '文章标题',
example: '标题',
})
title: string;
@ApiProperty({ description: '文章内容', example: '内容' })
content: string;
}
@Controller('posts')
@ApiTags('Posts')
export class PostsController {
@Get()
@ApiOperation({
summary: '获取文章列表数据',
})
async index() {
return await PostModel.find();
}
@Post()
@ApiOperation({
summary: '创建文章',
})
async create(@Body() createPostDto: CreatePostDto) {
const data = await PostModel.create(createPostDto);
return {
success: 0,
data,
};
}
@Get(':id')
@ApiOperation({
summary: '获取文章详情',
})
async detail(@Param('id') id: string) {
return await PostModel.findById(id);
}
@Put(':id')
@ApiOperation({
summary: '编辑文章',
})
async update(
@Param('id') id: string,
@Body() createPostDto: CreatePostDto
) {
await PostModel.findByIdAndUpdate(id, createPostDto);
const data = await PostModel.findById(id);
return {
success: 0,
data,
};
}
@Delete(':id')
@ApiOperation({
summary: '删除文章',
})
async remove(@Param('id') id: string) {
const res = await PostModel.findByIdAndDelete(id);
return {
success: 0,
data: res,
};
}
}
测试接口可以使用上一篇提到的 api-docs 地址,来查看接口是否添加成功。
数据验证
当前端传输数据给后端时,后端也要做数据的校验规则,不然传输什么就接受什么,对程序来说也是不健全的。下载相应的依赖
npm i class-validator class-transformer --save
class-validator
数据校验class-transformer
数据转换
下载依赖后,需要在入口文件 main.ts
添加全局管道
TS
// 添加全局验证
app.useGlobalPipes(new ValidationPipe());
这里的管道相当于中间件,所有的输入输出都会要走管道逻辑。接着我们可以在 DTO
上装饰接口参数
TS
import { IsNotEmpty } from 'class-validator';
class CreatePostDto {
@ApiProperty({
description: '文章标题',
example: '标题',
})
@IsNotEmpty({
message: '请填写标题!',
})
title: string;
@ApiProperty({ description: '文章内容', example: '内容' })
content: string;
}
可以对参数的类型进行校验
总结
这篇完善了接口的增删改查,对接口的文档进行补充,接口参数怎么校验,数据库怎么连接操作;也看到 Nest
这个框架依赖于各种装饰器来简化我们的业务操作。