【小白鲨笔记】Nestjs(五)

本文详细介绍了Nest.js中的控制器设计,包括如何使用装饰器快速配置、处理请求与响应,以及遵循RESTful风格的API设计原则。重点讲解了CRUD操作与状态码管理,展示了动态路由和版本控制的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

五、控制器 Controllers

控制器:负责处理客户端的请求数据,并将结果返还。它的目的就是接收客户端的各种任务,这个机制则是用了类似前端路由的一种控制。路由是将所需要的请求放在不同的 URL 中,根据不同的需求,访问不同的 URL。

Nest 的控制器一般都使用装饰器进行快速的配置、接收请求。Nest 提供了一个快速创建 CRUD 控制器的生产方法:nest g resource [组件名称]

Nest 提供了很多的装饰器帮助开发者快速获取请求参数等,其中常用的有:

装饰器介绍
@Controller(route?:string)控制器类上必加:让程序识别控制器
@Request() / @Req()接收请求参数
@Response() / @Res()接收返回参数
@Param(key?:string)接收请求参数中的param(需要在路由中标记)
@Body(key?:string)接收请求参数中的body(post)
@Query(key?:string)接收请求参数中的query(get)
@Headers(name?:string)接收请求头
@HttpCode()设置返回状态码
@Session()设置session(需要安装express-session)
@Redirect(url:string, statusCode:number)重定向:需设置地址和状态码(3xx)

Nest 采用的请求风格是RESTful API 接口的设计风格。REST 是一种体系结构样式,一般用于web服务开发。REST 的出现是为了解决,当需要请求复杂的数据时,需要个固定的模式,这样对于开发者来说,代码请求会更加的有组织、简洁。

在 URL 设置方面,REST 的请求参数则是通过 ‘/’,而非像传统形式的 ‘?’:

  • 传统URL带参数:http://localhost:8080/api/get?id=1
  • REST风格URL:http://localhost:8080/api/1

对于增删改查的操作,REST 则是通过不同的请求方式来区分,这样即便时同一个接口也可以实现不同的操作。它遵循的是CRUD操作,各对应了:

操作Http 方法
C = Create(增)POST
R = Read(查)GET
U = Update(改)PUT
D = Delete (删)DELETE

对比传统设计风格可以明显看出有所不同。传统方式会以不同URL进行不同的操作。而遵循 REST 风格的web应用(RESTful)的 URL 是不变的,只是根据不同的Http请求方法,提供了不同的服务,并且用 Http 协议中的 status code 定义操作结果。

操作传统设计REST架构
查询/user/getUserGET /user
新增/user/addUserPOST /user
更新/user/updateUserPUT /user
删除/user/deleteUserDELETE /user

当然,这只是一套规范,写项目时只是建议这样写,但不是必须遵循的。

Get请求

Get 请求必须在方法之上加入 @Get() 装饰器,路由参数可以选择填入或否。Get 请求参数可以通过 @Req() 或者 @Query() 装饰器获取,相同的方式,@Headers() 也可以获取请求头部信息。也可以选择直接选取并获得参数中的某个元素,只需要在装饰器中传入对应的元素名称即可。

import { Controller, Get, Req, Query, Headers } from '@nestjs/common';
import { DemoService } from './demo.service';
 
@Controller('demo')
export class DemoController {
  constructor(private readonly demoService: DemoService) { }
 
  @Get()
  getData(@Req() req, @Query() query, @Headers('cookie') cookie) {
    console.log(req.query === query) // true
    console.log(cookie) // 从请求头部中直接获取cookie
    return { code: 200 }
  }
}
Post请求

Post 请求参数同样可以通过 @Req() 来获取,或者直接接收 @Body() 参数,亦或者直接传入参数名称。

import { Controller, Post, Body, Req } from '@nestjs/common';
import { DemoService } from './demo.service';
 
@Controller('demo')
export class DemoController {
  constructor(private readonly demoService: DemoService) { }
  
  @Post()
  create (@Req() req, @Body('name') body) {
    console.log(req.body, body.name) // 可获取请求体中的name元素
    return { code:200 }
  }
}
动态路由

Nest 应用中可以接收动态参数,通过此参数访问不同的网页。接收方式同样可以使用 @Req(),又或者用 @Param() 直接接收。

import { Controller, Get, Param, Req } from '@nestjs/common';
import { DemoService } from './demo.service';
 
@Controller('demo')
export class DemoController {
  constructor(private readonly demoService: DemoService) { }
  
  @Post(':id') //路由为:localhost:port/demo/1
  create (@Req() req, @Param() param) {
    console.log(req.param) // { id: 1 }
    console.log(param.id) // 1
    return { code:200 }
  }
}
状态码

通过 @HttpCode() 可以直接返还对应的状态码。在 REST 接口中,通常也有状态码的代码规范:

  • 2xx开头:成功
    • 200 OK(操作成功,正常返回)
    • 201 Created(操作成功,已经在处理该请求)
    • 202 Accepted(异步处理)
  • 3xx开头:重定向(参数方面异常)
    • 300 Multiple Choices(参数类型错误)
    • 301 Moved Permanently(资源地址已更新)
    • 302 Found(参数超出正常取值范围)
    • 303 See Other(token过期)
    • 304 Not Modified(token无效)
  • 4xx开头:客户端异常(请求地址异常)
    • 400 Bad Request(找不到地址)
    • 401 Unauthorized(token错误)
    • 403 Forbidden referer origin(验证失败)
    • 404 Not Found(接口不存在)
    • 406 Not Acceptable(服务端不支持所需表示)
    • 409 Conflict(通用冲突)
  • 5xx开头:服务端异常
    • 500 Internal Server Error(服务端错误)
    • 501 Not Implemented(不存在)
    • 502 Bad Gateway(上有接口或者服务器有问题)
    • 503 Service Unavailable(服务端当前无法处理请求)

在 Nest 项目中,通过装饰器或者直接返回状态码结果都是可以的。

import { Controller, Post, HttpCode } from '@nestjs/common';
import { DemoService } from './demo.service';
 
@Controller('demo')
export class DemoController {
  constructor(private readonly demoService: DemoService) { }
  
  @Post()
  @HttpCode(500)
  create () {
    return { }
  }
}
REST版本控制

REST API 定义版本控制是为了解决一些版本不兼容的问题。可以使用不同的 URL 对应不同的版本,这样可以做到同时兼容多个版本。

RESTful 中拥有三种不同的版本控制类型,一般使用默认的 URI 资源定位符。

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

Nest 中需要先在入口文件导入:

import { NestFactory } from '@nestjs/core';
import { VersioningType } from '@nestjs/common';
import { AppModule } from './app.module';
 
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableVersioning({ type: VersioningType.URI })
  await app.listen(3000);
}
bootstrap();

接下来就可以直接在控制器中使用不同的版本。第一种方式是直接将整个控制器放在同一个版本,在 @Controller 装饰器上设置。另一种则是通过 @Version 装饰器设置某个特定的接口的版本。

import { Controller, Get, Version } from '@nestjs/common';
import { DemoService } from './demo.service';
 
@Controller({
  path: 'demo', // 路由地址可以通过path传递
  version:'1' // 1. 设置整个控制器版本
})
export class DemoController {
  constructor(private readonly demoService: DemoService) {}
 
  @Get()
  // @Version('1') // 2. 指定接口本版
  getVersion() { return 'Version 1' }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值