携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
nest 接口开发入门实战
技术栈
后端框架: nest.js
数据库: mysql
orm框架: typeorm
创建项目
npm i -g nest
nest new your-project-name
创建完项目,如果发现文件出现了这种错误 Delete ␍eslintprettier/prettier ,在 prettierrc 加入 "endOfLine": "auto",并且重新加载vscode窗口,保存就好了。
运行npm run start之后,打开http://localhost:3000,看到不是空白页面就算成功了
新手可能一开始都不知道为什么是3000端口并且运行也没有任何提示,其实它在入口文件main.ts里面可以看到:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000); // 端口
}
接下来我们修改一下端口并输出提示到终端
1. 修改端口输出运行端口日志
vscode把鼠标移动到app.listen上,可以看到listen(port: string | number, callback?: () => void)
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 这个 port 可以专门放到一个地方去
const post = 5000
await app.listen(port, () => {
console.log(`server started at ${port}`)
}); // 端口
}
npm run start
// 看到输出如下
// server started at 5000
2. 重载模式
我们想修改代码的时候像nodemon或者webpack一样,不用重启项目,能自动重载
使用npm run start:dev启动项目
这样你每次修改项目代码,它都会自动重载项目。
3. 创建第一个模块
Nest.js 默认提供了基于 express 封装的 MVC 架构。
MVC 是 Model View Controller 的简写,在 MVC 架构下,请求会先发送到 Controller ,由它去调用 Model 层的 Service 来完成业务逻辑,返回对应的 View
- Controller:由 @Controller() 来声明,它负责提供接口、处理路由、包括请求头,重定向等等;
- Service:由 @Injectable() 来声明,作为服务,它负责处理复杂的业务逻辑,比如数据库的增删改查等操作;
- Module:由 @Module() 来声明,作为 IOC 容器,它会实例化 Controller,查找依赖项,然后创建 Service 实例并且返回,这其实就是依赖注入。
下面我们新增 test 模块来做第一个demo
使用 Nest CLI
使用 Nest CLI 创建模块
nest g 文件类型 文件名 【文件目录(默认在src下面)】
运行命令创建 Controller 和 Service
nest g controller modules/test;
会生成如下目录:
📦modules
┗ test
┃ ┣ 📜test.controller.spec.ts
┃ ┣ 📜test.controller.ts
创建完成后,appModule会自动引入它,只有在 @Module 中引入 Controller 才能使用,后面我们会拆分模块。
controllers: [AppController, TestController],
spec 这个我还没用过,但是看它应该是作为测试用的,我们不管它。
接收五种类型参数的接口
接下来分别实现接受 url param,query,form data,html urlencoded,json 的接口,然后使用 axios 发送请求。
在此之前,后端先解决一下跨域问题
// main.ts
const app = await NestFactory.create(AppModule, {
cors: true
});
test.controller.ts
import {
Body,
Controller,
Get,
Param,
Post,
Query,
UploadedFiles,
UseInterceptors,
} from '@nestjs/common';
import { AnyFilesInterceptor } from '@nestjs/platform-express';
@Controller('test')
export class TestController {
// query
@Get('query')
testQuery(
@Query('page_size') page_size: number,
@Query('page') page: number,
) {
return `page_size=${page_size},page=${page}`;
}
// param
@Get(':id')
testParam(@Param('id') id: string) {
return `id= ${id}`;
}
// html urlencoded / json
@Post('create')
testUrlencoded(@Body() create: { name: string; age: number }) {
return create;
}
// formData
// npm install --save @types/multer @nestjs/platform-express
@Post('file')
@UseInterceptors(AnyFilesInterceptor())
async uploadFile(
@Body()
query: {
name: string;
age: number;
},
@UploadedFiles() file: Array<Express.Multer.File>,
) {
const obj = {
query,
file,
};
return obj;
}
}
app.vue
<script setup>
import axios from 'axios'
import qs from 'qs'
import { ref } from 'vue'
const fetch = async () => {
const result1 = await axios.get('http://localhost:5000/test/query', {
params: {
page_size: 10,
page: 1,
},
})
console.log(result1.data)
const result2 = await axios.get('http://localhost:5000/test/123')
console.log(result2.data)
const result3 = await axios.post(
'http://localhost:5000/test/create',
qs.stringify({
name: '123',
age: 12,
}),
{
headers: { 'content-Type': 'application/x-www-form-urlencoded' },
}
)
const result4 = await axios.post('http://localhost:5000/test/create', {
name: '123',
age: 12,
})
console.log(result3.data)
console.log(result4.data)
}
const file = ref()
const handleChange = async () => {
const data = new FormData()
data.append('a', 12)
data.append('b', 'asd')
data.append('file', file.value.files[0])
const result = await axios.post('http://localhost:5000/test/file', data, {
headers: { 'content-type': 'multipart/from-data' },
})
console.log(result.data)
}
fetch()
</script>
<template>
<input type="file" ref="file" @change="handleChange" />
</template>
感谢阅读。