Controllers
Controllers主要是用来处理客户端的请求Request和返回Response的。
路由
实际试一下Controllers的路由功能。先通过上一篇文章的方法新建一个新的工程,然后用命令行工具进到工程根目录,执行下面的命令。创建一个Cats模块。
# -d干燥模式看下是否是自己想创建的东西,执行完后显示以下内容,但是不会真的创建文件
# CREATE src/cats/cats.module.ts (81 bytes)
# UPDATE src/app.module.ts (308 bytes)
nest g module cats -d
# 确认没问题后,去掉干燥模式
nest g module cats
# 干燥模式确认Controller
# CREATE src/cats/cats.controller.spec.ts (478 bytes)
# CREATE src/cats/cats.controller.ts (97 bytes)
# UPDATE src/cats/cats.module.ts (166 bytes)
nest g co cats -d
# 会创建测试文件(spec.ts),这里不需要,所以去掉测试创建
nest g co cats --no-spec
查看工程目录,生成2个文件
打开cats.controller.ts文件,修改里面的代码
import { Controller ,Get } from '@nestjs/common';
/**
* @Controller装饰器,这里的参数cats就等于给这个路由加了一个前缀,
* 在这个实例里面请求的路径是 /cats
*/
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}
@Get装饰器,用来装饰方法findAll来告诉NestJS要通过Get请求来访问这个方法。也可以在装饰器里面传入参数,比如@Get('info'),那么访问地址就会变成\cats\info,通过上面的例子浏览器会返回一串字符串。
- Nest使用两种不同选项来操纵响应的概念: 标准 (推荐) | 使用此内置方法,当请求处理程序返回JavaScript对象或数组时,它将自动序列化为JSON。然而,当它返回JavaScript基元类型(例如,“string”、“number”、“boolean”)时,Nest将只发送值,而不尝试对其进行序列化。这使得响应处理变得简单:只返回值,Nest处理其余的值。此外,默认情况下,响应的状态代码始终为200,除了使用201的POST请求。我们可以通过在处理程序级别添加“@HttpCode(…)”装饰器来轻松地更改此行为(请参见状态代码)。 | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 特定库 | 我们可以使用库特定的(例如,Express)响应对象,可以使用方法处理程序签名中的“@Res()”修饰符(例如,“findAll(@Res)response)”)注入。通过这种方法,您可以使用该对象公开的本机响应处理方法。例如,使用Express,您可以使用类似“response.status(200).send()”的代码构造响应。|
注意: Nest检测处理程序何时使用@Res()或@Next(),表示您选择了库特定的选项。如果同时使用两种方法,则该单一路线的标准方法将自动禁用,不再按预期工作。要同时使用这两种方法(例如,通过注入响应对象以仅设置cookies/header,但仍将其余部分留给框架),必须在@Res({passthrough:true})修饰符中将passthrough选项设置为true。
请求对象
很多情况下,处理请求需要获得请求中的参数,一般使用@req来获取请求的内容
import { Controller ,Get, Req, Bind } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** 请求对象 */
// 请求后返回 This action returns all cats/cats/request1
@Get('request1')
findAll_req1(@Req() request: Request): string {
return 'This action returns all cats'+ request.url;
}
// 请求后返回 This action returns all cats/cats/request1
@Get('request2')
@Bind(Req())
findAll_req2(request): string {
return 'This action returns all cats'+ request.url;
}
}
@req()返回的是请求头的全部内容,通常情况下不要获取这么大的一个对象,可以使用@Body @Query来去的Request里面具体的对象
| 装饰器 | 实际取得内容(默认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 |
Resources
以上我们都是用的@Get装饰器来处理Get请求,我们还可以通过@Post来处理post请求,可以通过Postman来发出Post请求下面接口
import { Controller ,Get, Req, Bind, Post } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** Resources */
@Post()
create(): string {
return 'This action adds a new cat';
}
}
Nest还提供了@Get(), @Post(), @Put(), @Delete(), @Patch(), @Options(),@Head(), @All()修饰器。
路由通配符
用*通佩服可以匹配任何字段。abcd, ab_cd, abecd这些路径名称都会被匹配。通配符还可以使用正则表达式。
import { Controller ,Get, Req, Bind, Post } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** 路由通配符 */
@Get('ab*cd')
findAll_wildcards() {
return 'This route uses a wildcard';
}
}
请求结果
状态码
一般情况下,返回的状态码是200,Post返回的是201,可以自定义状态码。
import { Controller ,Get, Req, Bind, Post, HttpCode } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** 状态码 */
// 返回状态码 204
@Post()
@HttpCode(204)
create_status_code() {
return 'This action adds a new cat';
}
}
以上的方式是静态的,也可以通过@Res()动态的设定状态码,或者通过抛出内置异常等来设定状态码
返回Header头
可以通过@Header自定义返回的Header
import { Controller ,Get, Req, Bind, Post, HttpCode, Header } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** 返回头 */
@Post()
// 指定返回头中的内容
@Header('Cache-Control', 'none')
create_header() {
return 'This action adds a new cat';
}
}
通过postman确认
重定向
要将响应重定向到特定的URL,可以使用@redirect()装饰器或库特定的响应对象(并直接调用res.redirect())。
@Redirect()接受一个必需的url参数和一个可选的statusCode参数。如果省略,statusCode默认为302。
import { Controller ,Get, Req, Bind, Post, HttpCode, Header,Redirect } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** 重定向 */
// 访问 http://localhost:3000/cats/redirect 跳转到 'nestjs.com'
@Get('redirect')
@Redirect('https://nestjs.com', 301)
// 任意方法名
redirect(){}
}
有时您可能需要动态确定HTTP状态代码或重定向URL。为此,请从路由处理程序方法返回一个具有以下形状的对象
{
"url": string,
"statusCode": number
}
例子:
import { Controller ,Get, Req, Bind, Post, HttpCode, Header,Redirect, Query } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/*
* 访问 http://localhost:3000/cats/docs?version=5 跳转到 https://docs.nestjs.com/v5/'
* 访问 http://localhost:3000/cats/docs 跳转到 https://docs.nestjs.com'
*/
@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
if (version && version === '5') {
return { url: 'https://docs.nestjs.com/v5/' };
}
}
}
路由参数
当您需要接受动态数据作为请求的一部分时(例如,GET/cats/1获取id为1的cat),带有静态路径的路由将无法工作。为了用参数定义路由,我们可以在路由的路径中添加路由参数标记,以捕获请求URL中该位置的动态值。下面@Get()装饰器示例中的路由参数标记演示了这种用法。可以使用@Param()修饰符访问以这种方式声明的路由参数,该修饰符应添加到方法签名中。
import { Controller ,Get, Req, Bind, Post, HttpCode, Header,Redirect, Query, Param } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** 路由参数 */
@Get('param1/:id')
findOne1(@Param() params): string {
console.log(params.id);
return `This action returns a #${params.id} cat`;
}
@Get('param2/:id')
@Bind(Param())
findOne2(params) {
console.log(params.id);
return `This action returns a #${params.id} cat`;
}
}
@Param()用于修饰方法参数(上例中的params),并使路由参数作为该修饰方法参数在方法体内的可用。如上面的代码所示,我们可以通过引用params.id来访问id参数。您还可以将特定的参数令牌传递给decorator,然后在方法体中直接通过名称引用路由参数。
import { Controller ,Get, Req, Bind, Post, HttpCode, Header,Redirect, Query, Param } from '@nestjs/common';
@Controller('cats')
export class CatsController {
/** 路由参数 */
@Get('param1/:id')
findOne1(@Param() params): string {
console.log(params.id);
return `This action returns a #${params.id} cat`;
}
@Get('param2/:id')
@Bind(Param())
findOne2(params) {
console.log(params.id);
return `This action returns a #${params.id} cat`;
}
@Get('param3/:id')
findOne3(@Param('id') id: string): string {
return `This action returns a #${id} cat`;
}
@Get('param4/:id')
@Bind(Param('id'))
findOne4(id) {
return `This action returns a #${id} cat`;
}
}