创建项目
先创建一个 nestjs 项目
npm i -g @nestjs/cli // 全局安装Nest
nest new project-name // 创建项目
- 目录结构
src
├── app.controller.spec.ts————针对控制器的单元测试
├── app.controller.ts————单个路由的基本控制器(Controller)
├── app.module.ts————应用程序的根模块(Module)
├── app.service.ts————具有单一方法的基本服务(Service)
├── main.ts————应用程序的入口文件,它使用核心函数 NestFactory 来创建 Nest 应用程序的实例。
main.ts
- 主入口程序
// main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
app.module.ts
- 应用程序的根模块
controllers
:处理 http 请求,包含路由、客户端返回响应请求、将业务逻辑交给providers
处理。providers
:Nest.js
注入器实例化的提供者(服务提供者),处理具体的业务逻辑。imports
:导入模块列表,如果使用其他模块则导入exports
:导出服务的列表
// app.module.ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
app.controller.ts
@Controller()
:定义控制器@GET()
:请求方法的装饰器,GET 请求时会调用下面的getHello()
方法
// app.controller.ts
import { Controller, Get } from "@nestjs/common";
import { AppService } from "./app.service";
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
@Header("Cache-Control", "none") // 定义响应头
getHello(): string {
return this.appService.getHello();
}
}
app.service.ts
// app.service.ts
import { Injectable } from "@nestjs/common";
@Injectable()
export class AppService {
getHello(): string {
return "Hello World!";
}
}
命令
- 快捷创建文件
# 语法
nest g [文件类型] [文件名] [文件目录]
- 功能:在 src 下自动创建模块
mo
:Moduleco
:controller
nest g mo cat
nest g service cat
nest g co cat
注意创建顺序: 先创建Module
, 再创建Controller
和Service
, 这样创建出来的文件在Module
中自动注册,反之,后创建 Module, Controller
和Service
,会被注册到外层的app.module.ts
Controller 控制器
路由前缀
- 1)
@Controller('cats')
- 设置前缀,访问
http://localhost:3000/cats
- 设置前缀,访问
注意!!!这里并不是只能使用 Get
请求,也可以使用:@Get()
、@Post()
、@Put()
、@Patch()
、@Delete()
、@Options()
、@Head()
、@All()
import { Controller, Get } from "@nestjs/common";
import { CatsService } from "./cats.service";
@Controller("cats") // 访问 http://localhost:3000/cats
export class CatsController {
constructor(private readonly catsService: CatsService) {}
// Get 请求
@Get()
getCats(@Request() req: Request): string {
console.log(req);
return "cats";
}
}
路由匹配与参数获取
- 1)我们先说 路由匹配
- 一种是通配符,一种是带参数
- 2)获取参数
- 我们使用
@Body()
、@Query()
、@Param()
这样的参数装饰器,获取参数。下面有个表就是 Nest 对比 Express 。
- 我们使用
@Request(),@Req() | req |
@Response(),@Res()* | res |
@Next() | next |
@Session() | req.session |
@Param(key?: string) | req.params /req.params[key] |
@Body(key?: string) | req.body /req.body[key] |
@Query(key?: string) | req.query /req.query[key] |
@Headers(name?: string) | req.headers /req.headers[name] |
@Ip() | req.ip |
@HostParam() | req.hosts |
import { Controller, Req, Param, Get } from "@nestjs/common";
import { CatsService } from "./cats.service";
import { Request } from "express";
@Controller("cats")
export class CatsController {
constructor(private readonly catsService: CatsService) {}
// 1. 通配符
// 匹配所有 cat/lists 开头的地址
@Get("lists*")
getLists(): string {
return "Cat-Lists-*";
}
// 2. 获取 Param 参数
// url: http://localhost:3000/cats/list123
// return: list123
@Get(":id")
getId(@Param("id") id): string {
return id;
}
// 3. 获取 req
@Get("")
getReq(@Req() req: Request): Request {
console.log(req);
return req;
}
}
状态码
修改状态码
@Post()
@HttpCode(204)
async create() {
return 'This action adds a new cat';
}
响应头
@Post()
@Header('Cache-Control', 'none')
async create() {
return 'This action adds a new cat';
}
重定向
@Get()
@Redirect('https://nestjs.com', 301)
如果想动态传递
@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
if (version && version === '5') {
return { url: 'https://docs.nestjs.com/v5/' };
}
}
@Get()
redirect(@Res() res) {
return res.redirect('/books/greet');
}
异步
@Get()
async findAll(): Promise<any[]> {
return [];
}
请求负载
建议使用类,因为它们在编译后的 JavaScript 中被保留为实际实体。另一方面,由于 TypeScript 接口在转换过程中被删除,所以 Nest 不能在运行时引用它们。
这一点很重要,因为诸如管道(Pipe)之类的特性为在运行时访问变量的元类型提供更多的可能性。
/*
create-cat.dto.ts
*/
export class CreateCatDto {
readonly name: string;
readonly age: number;
readonly breed: string;
}
/*
cats.controller.ts
*/
@Post()
async create(@Body() createCatDto: CreateCatDto) {
return 'This action adds a new cat';
}