控制器负责处理传入的请求并将响应返回给客户端。而路由的职责用于执行匹配路由后的逻辑,一个Controller可以可以有多个路由。Nest提供了一系列装饰器用于处理请求与响应,学习过这些装饰器后一切将变得非常简单。
1.@Controller标识当前类是一个控制器
@Controller装饰器标识当前类是一个控制器,@Controller可以指定一个路径前缀,用于控制器分组。
/*
* 不加路径前缀的Controller例子,假设应用端口为3000
*/
import {Controller,Get} from '@nestjs/common';
@Controller
export class AppController {
/*
* 访问localhost:3000/findUser即可成功调用接口
*/
@Get("/findUser")
findUser():object{
return {name:"zxp",id:1}
}
}
/*
* 加路径前缀的Controller例子,假设应用端口为3000
*/
import {Controller} from '@nestjs/common';
@Controller("/user")
export class AppController {
/*
* 访问localhost:3000/user/findUser即可成功调用接口
*/
@Get("/findUser")
findUser():object{
return {name:"zxp",id:1}
}
}
2.@Get、@Post处理不同请求类型路由
这些装饰器用于处理请求路由:
@Get用于处理指定路由的GET请求。若以其他请求类型访问@Get路由则会报404错误。
@Post用于处理指定路由的POST请求。若以其他请求类型访问@Post路由则会报404错误。还有其他请求类型,非常简单没什么好说。
3.@Request和@Req获取Request对象
@Requst和@Req注解用于获取请求对象,@Request与@Req作用是一样的,@Req是@Request的简写。通过请求对象可以获取请求的query、param、body、headers、ip、host等信息,@Query、@Param、@Body等装饰器是对请求对象进一步封装。请求对象的类型取决你用的web框架,如果你使用的express就从express包导入,使用的web框架是fastify就从fastify导入Request对象。
import {Controller,Req,Get} from '@nestjs/common';
@Controller
export class AppController {
@Get("/getReq")
getReq(@Req() req):Request{
/**
* 假设访问localhost:3000/getReq?name=zxp
*/
console.log('query:', req.query); //query: { name: 'zxp' }
console.log('params:', req.params);
console.log('body:', req.body);
console.log('headers:', req.headers);
console.log('ip:', req.ip); //ip: ::1
console.log('host:', req.host); //host: localhost
return req;
}
}
4.@Query获取请求查询参数
@Query注解用于获取请求URL上的查询参数,也就是请求url中?号后面的参数。
import {Controller,Req,Get,Query} from '@nestjs/common';
@Controller
export class AppController {
//@Query写法1:参数写法,允许为参数添加类型,这一点是很重要的,推荐这种写法
@Get("/getQueryParams")
getQueryParams(@Query() id:number):string{
//假设访问localhost:3000/getQueryParams?id=1
console.log(id); //1
return "参数是:"+id;
}
//@Query写法2:结构写法,参数无法添加类型,但是很方便
@Get("/getUser")
getUser(@Query(){id}):string{
//假设访问localhost:3000/getQueryParams?id=1
console.log(id); //1
return "参数是:"+id;
}
}
5.@Param获取路由参数
@Param装饰器用于获取路由上的参数,一般用于获取动态路由的参数。
import {Controller,Get,Param} from '@nestjs/common';
@Controller
export class AppController {
@Get("/getParams/:id")
getParams(@Param() id:number):number{
//假设访问localhost:3000/getParams/1
console.log(id);//1
return "获取param参数为:"+id;
}
}
6.@Body获取表单数据
@Body可以获取以x-www-form-urlencoded和raw格式提交的数据。
import {Controller,Post,Body} from '@nestjs/common';
@Controller
export class AppController {
@Post("/addUser")
addUser(@Body() data):object{
console.log(data);
return data
}
}
7.@Response和@Res获取响应对象
@Response和@Res可以获取响应对象,@Res和@Response具有一样的作用,@Res是@Response的简写,通过响应对象可以设置响应状态码、响应数据格式等等。
import {Controller,Get,Res,HttpStatus} from '@nestjs/common';
import { Response} from 'express';
@Controller
export class AppController {
/*
* 响应状态码为200并以json格式响应。
*/
@Get("/findUser")
findUser(@Res() res):Response{
return res.status(HttpStatus.OK).json({name:"zxp"});
}
}
8.@Headers获取请求头信息
import {Controller,Get,Headers} from '@nestjs/common';
@Controller
export class AppController {
@Get("/getUser")
getUser(@Headers() headers){
const obj = {
'user-agent': 'PostmanRuntime/7.26.3',
accept: '*/*',
'postman-token': '1e4c5aa7-918c-4363-bc13-bbfcce27565e',
host: 'localhost:3000',
'accept-encoding': 'gzip, deflate, br',
connection: 'keep-alive',
};
return header; // 结果为obj的内容
}
}
9.@Redirect转发路由
@Redirect装饰器用于请求转发。
import {Controller,Get,Redirect} from '@nestjs/common';
@Controller
export class AppController {
@Get("/redirect")
@Redirect("http://localhost:3000/getUser") //转发到/getUser路由
redirect(){
console.log("转发请求...");
}
@Get("/getUser")
getUser():object{
return {name:"zxp'}
}
}
10.@HttpCode设置响应状态码,@Header用于设置响应头
@HttpCode用于设置响应状态码,如果不显示设置响应状态码则默认是200。
import {Controller,Get,HttpCode,Header} from '@nestjs/common';
@Controller
export class AppController {
//当访问localhost:3000/setResCode时状态码为204 No Content
@Get("/setResCode")
@HttpCode(204)
@Header('Cache-Control', 'none') //设置响应头,表示不开启缓存
setHttpCode(){
return "204..."
}
}
11.@Bind用于将包装的装饰器绑定到路由方法的参数
@Bind装饰器的作用是将包装的装饰器绑定到路由方法的参数,这样可以不用在路由方法中使用装饰器而获得同样的功能。
import {Controller,Get,Req,Res,Query} from '@nestjs/common';
@Controller
export class AppController {
@Bind(Req(),Res(), Query())
bind(req,res, query) {
console.log('请求对象:', req);
console.log('响应对象:', res);
console.log('请求查询参数对象:', query);
}
}
完整的例子:
import {
Controller,
Get,
Query,
Req,
Post,
Body,
Param,
Delete,
Res,
HttpCode,
Headers,
Ip,
Redirect,
Header,
HttpStatus,
Session,
Bind
} from '@nestjs/common';
import { Request,Response} from 'express';
import { AppService } from './app.service';
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
id: i,
name: `user-${i}`,
});
}
/**
* @Controller可以接收一个参数用于区分路由分组
*/
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('/hello')
getHello(): string {
return this.appService.getHello();
}
/**
* @Query装饰器用于获取请求url的查询参数(?号后面的参数),@Query相当于@Req的res.query,@Query有两种写法:
* 第一种是正常的方法写法,例如@Query(id:number,name:string),这种写法可以使用ts指定参数类型(推荐)。
* 第二种是结构写法,例如@Query(){id,name},这种写法无法使用ts指定参数类型。
*
* 访问 http://localhost:3000/findUser?id=1&name=user-1
* 结果为: {"id":1,"name":"user-1"}
*/
@Get('/findUser')
findUser(@Query() { id, name }): object {
return data.filter(
(item) => item.id == id && item.name.indexOf(name) > -1,
)[0];
}
/**
*
* @Body可以获取以x-www-form-urlencoded和raw格式提交的数据
*/
@Post('/addUser')
addUser(@Body() body): object {
/**
* 假设使用Postman以raw格式提交的数据内容为{"id":1}
*/
console.log(body); //{id:1}
return body;
}
/**
* @Param可以获取请求URL中的参数,一般用于获取动态参数,
* 例如访问localhost:3000/1,下面例子中id的值为1
*/
@Delete(':id')
delUser(@Param() { id }): string {
console.log(id); //1
return '删除成功';
}
/**
* @Headers 用于获取请求头对象
*/
@Get('/getHeader')
getHeader(@Headers() header): object {
const obj = {
'user-agent': 'PostmanRuntime/7.26.3',
accept: '*/*',
'postman-token': '1e4c5aa7-918c-4363-bc13-bbfcce27565e',
host: 'localhost:3000',
'accept-encoding': 'gzip, deflate, br',
connection: 'keep-alive',
};
return header; // 结果为obj的内容
}
/**
* @Header装饰器用于设置响应头信息。
* @Ip装饰器用于获取请求ip。
*/
@Get('/getIp')
@Header('Cache-Control', 'none')
getIp(@Ip() ip): string {
return '请求ip为:' + ip; //请求ip为:::1
}
/**
* @Session用于获取请求Session信息
*/
@Get('/getSession')
getSession(@Session() session) {
return 'session:' + session;
}
/**
* @HttpCode装饰器用于设置响应状态码,如不显示设置默认为200,
* 当访问localhost:3000/setResCode时状态码为204 No Content
*/
@Post('/setResCode')
@HttpCode(204)
setResCode(): string {
return '响应成功';
}
/**
*@Redirect装饰器用于路由转发
*/
@Get('/redirect')
@Redirect('http://localhost:3000/findAll', 200)
redirect() {
return '转发成功';
}
/**
* @Request和@Req装饰器用于设置请求对象,@Req是@Request的简写,它们的作用都是一样的,
* 通过请求对象可以获取到query、param、body、ip、headers、host、hosts等参数,
* 像@Query、@Param、@Body、@Ip等等这些装饰器都是对请求对象进一步封装。
*/
@Get('/findAll')
findAll(@Req() req): Request {
/**
* 假设访问localhost:3000/findAll?name=zxp
*/
console.log('query:', req.query); //query: { name: 'zxp' }
console.log('params:', req.params);
console.log('body:', req.body);
console.log('headers:', req.headers);
console.log('ip:', req.ip); //ip: ::1
console.log('host:', req.host); //host: localhost
return req;
}
/**
* @Response和@Res装饰器用于设置响应对象,@Res装饰器是@Response的简写,它们的作用是一样的
* 通过响应对象你可以设置响应状态码、响应格式等等。
* res.status(HttpStatus.OK) 用于设置响应状态码为200,
* json()用于将数据转为json格式
*/
@Get('/findList')
findList(@Res() res) {
return res.status(HttpStatus.OK).json({ name: 'zxp', id: 1 });
}
/**
* @Bind装饰器的作用是将包装的装饰器绑定到路由方法的参数,这样可以不用在路由方法中使用装饰器
* 而获得同样的功能。
*/
@Bind(Req(), Query())
bind(req, query) {
console.log('请求对象:', req);
console.log('请求查询参数对象:', query);
}
}