nest 接口开发入门实战

382 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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启动项目

alt

这样你每次修改项目代码,它都会自动重载项目。

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 paramqueryform datahtml urlencodedjson 的接口,然后使用 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>

感谢阅读。