Nest入门教程(二:NestJS CLI实战)

347 阅读4分钟

NestJS 是一个用于构建高效、可扩展的 Node.js 服务端应用程序框架,它采用了模块化架构和 TypeScript 的强大特性。Nest CLI 是官方提供的命令行工具,极大地简化了开发流程。

中文文档:nestjs.inode.club/

1.nestjs cli

通过cli创建nestjs项目

npm i -g @nestjs/cli
nest new [项目名称]

CLI 会提示你选择包管理器(npm / yarn / pnpm),随后会自动初始化 TypeScript 项目并安装依赖。

目录结构

创建后的项目结构如下:

src/
  app.controller.ts      // 控制器
  app.service.ts         // 服务
  app.module.ts          // 根模块
  main.ts                // 应用入口

模块是 Nest 的核心,每一个功能模块都封装成独立的模块(Module),类似微服务架构中的服务单元。

main.ts

入口文件主文件 类似于vue 的main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

通过 NestFactory.create(AppModule) 创建一个app 就是类似于绑定一个根组件App.vue

app.listen(3000); 监听一个端口

Controller.ts 控制器

可以理解成vue 的路由

private readonly appService: AppService 这一行代码就是依赖注入不需要实例化 appService 它内部会自己实例化的我们主需要放上去就可以了


import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
 
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
 
  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}
 
//-----------------------------------------------------
//修改地址之后
 
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
 
@Controller('/get')
export class AppController {
  constructor(private readonly appService: AppService) {}
 
  @Get('/hello')
  getHello(): string {
    return this.appService.getHello();
  }

nest-cli1.png

service.ts

这个文件主要实现业务逻辑的 当然Controller可以实现逻辑,但是就是单一的无法复用,放到app.service有别的模块也需要就可以实现复用

import { Injectable } from '@nestjs/common';

// 使用@Injectable()装饰器将该类标记为可注入的provider
@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World';
  }
}

2.常用命令

nest --help 可以查看nestjs所有的命令

nest-cli2.png

案例生成一个用户模块

1.生成单个文件controller.ts、module.ts、service.ts

nest g co user
nest g mo user
nest g s user

mest-cli3.png

2.生成了一套标准的CURD 模板

使用 nest g resource user 可以一键生成 Module + Controller + Service + DTO。

nest g resource animal

mest-cli4.png

第一次使用这个命令的时候,除了生成文件之外还会自动使用 npm 帮我们更新资源,安装一些额外的插件,后续再次使用就不会更新了。

Nest CLI 还支持快速创建以下核心类:

类型命令描述
管道(Pipe)nest g pipe xxx用于数据验证与转换
守卫(Guard)nest g guard xxx权限拦截与控制
拦截器(Interceptor)nest g interceptor xxx用于处理请求/响应流
中间件(Middleware)nest g middleware xxx类似 Express 中间件
过滤器(Exception Filter)nest g filter xxx异常处理机制
网关(Gateway)nest g gateway xxxWebSocket 支持

3.构建符合 RESTful 规范的后端接口

什么是 RESTful 接口?

REST(Representational State Transfer)是一种资源导向的架构风格。其核心思想是:

  • 一切皆资源(用户、商品、文章等)
  • 使用 HTTP 方法明确操作(GET、POST、PUT、DELETE)
  • 使用统一的 URL 路径表示资源
方法路径描述
GET/users获取所有用户
GET/users/:id获取指定用户
POST/users创建新用户
PUT/users/:id更新用户
DELETE/users/:id删除用户

RESTful 实践建议

  1. 资源命名统一使用复数:如 /users、/posts,避免 /userList 这种业务词汇。
  2. 方法语义清晰
    • GET 查询
    • POST 创建
    • PUT/PATCH 更新
    • DELETE 删除
  3. 状态码语义明确
    • 200 OK 成功查询或删除
    • 201 Created 成功创建
    • 400 Bad Request 请求错误
    • 404 Not Found 资源不存在
    • 500 Internal Server Error 服务端错误
  4. 分页查询使用查询参数
GET /users?page=1&limit=10

5. 避免业务逻辑污染 REST 路由,比如:

// 不推荐
@Post('activate')  // /users/activate

// 推荐
@Patch(':id/activate') // /users/:id/activate

RESTful 版本控制

一共有三种我们一般用第一种 更加语义化

URI Versioning版本将在请求的 URI 中传递(默认)
Header Versioning自定义请求标头将指定版本
Media Type Versioning请求的Accept标头将指定版本

1.main.ts配合 app.enableVersioning() 实现 API 版本管理。

import { NestFactory } from '@nestjs/core';
import { UserModule } from './user/user.module';
import { VersioningType } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(UserModule);
  app.enableVersioning({
    type: VersioningType.URI,
  });

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

2.Controller 变成一个对象 通过version 配置版本

import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
} from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller({
  path: 'user',
  version: '1',
})
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.userService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.userService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.userService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.userService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.userService.remove(+id);
  }
}

nest-cli5.png