【NestJS系列】核心概念:Controller控制器
前言
控制器主要是用来处理客户端传入的请求并向客户端返回响应。
它一般是用来做路由导航的,内部路由机制控制哪个控制器接收哪些请求。
路由
为了创建基本控制器,我们需要使用@Controller装饰器,装饰器将类与所需元数据关联起来,并使Nest能够创建路由映射。
我们使用nest-cli快速创建一个REST API风格的完整CURD代码。
nest g resource nanjiu
在生成的nanjiu文件夹下,我们可以看到有nanjiu.controller.ts文件,代码如下:
// nanjiu.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';
import { NanjiuService } from './nanjiu.service';
import { CreateNanjiuDto } from './dto/create-nanjiu.dto';
import { UpdateNanjiuDto } from './dto/update-nanjiu.dto';
@Controller('nanjiu')
export class NanjiuController {
constructor(private readonly nanjiuService: NanjiuService) {}
@Post()
create(@Body() createNanjiuDto: CreateNanjiuDto) {
return this.nanjiuService.create(createNanjiuDto);
}
@Get()
findAll(@Param() params, @Query() query) {
console.log('find', query)
return this.nanjiuService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.nanjiuService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateNanjiuDto: UpdateNanjiuDto) {
return this.nanjiuService.update(+id, updateNanjiuDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.nanjiuService.remove(+id);
}
}
@controller装饰器中传入了nanjiu参数,表示指定路由前缀nanjiu,在@controller装饰器中使用路由前缀,可以让我们很轻松地将一组相关路由放在一起集中管理。
比如当我们通过get方式请求/nanjiu这个路由时,它应该会走到@get装饰器修饰的findAll方法内
可以使用ApiFox工具进行接口测试:
从上图中可以看到我此时的请求路径是http://localhost:3000/apinanjiu,是不是很好奇为了什么多了一层/api,这是因为我加了一层全局路由前缀
// main.ts
app.setGlobalPrefix('api'); // 全局路由前缀
这里我们还可以看到状态码为200,并且能够看到findAll的返回值,就说明此时的请求是正常的,但右边还有个error提示返回数据结构与接口定义不一致。
这是因为这里我们只是简单地返回了一个字符串,并不符合JSON格式
在Nest中,有两种选项来处理响应值:
标准模式:使用此内置方法,当请求处理程序返回 JavaScript 对象或数组时,它将自动序列化为 JSON。然而,当它返回 JavaScript 基本类型(例如,
string、number、boolean)时,Nest 将仅发送该值,而不尝试对其进行序列化。这使得响应处理变得简单:只需返回值,Nest 就会处理其余的事情。此外,默认情况下,响应的状态代码始终为 200,除了使用 201 的 POST 请求。我们可以通过
@HttpCode(...)在处理程序级别添加装饰器来轻松更改此行为特定库模式:我们可以使用特定于库的(例如,Express)响应对象
@Res(),可以使用方法处理程序签名中的装饰器注入该对象(例如,findAll(@Res() response))。通过这种方法,您可以使用该对象公开的本机响应处理方法。例如,使用 Express,可以使用response.status(200).send().
路由通配符
Nest还支持基于模式的路由,比如,使用通配符
@Get('ab*cd')
findAll() {
return 'This route uses a wildcard';
}
路由'ab*cd'路径将匹配abcd、ab_cd、abecd等。字符?、+、*和()可以在路由路径中使用,并且是其正则表达式对应项的子集。连字符 ( -) 和点 ( .) 按字面意思解释为基于字符串的路径。
请求对象
作为后端项目,访问客户端请求的详细信息也非常重要,从上面生成的代码中我们可以看到@Body、@Param、@Query等装饰器,没错,在大多数时候我们并不需要手动获取请求对象(查询字符串、参数、请求头、正文等),直接通过这些开箱即用的装饰器就能快速获取。
比如我们在findAll内加上日志
// nanjiu.controller.ts
@Get()
findAll(@Param() params, @Query() query) {
console.log('find', params, query) // 日志
return this.nanjiuService.findAll();
}
然后在请求时带上一些参数:
此时我们再来看看后端打印的日志:
这里就能看到前端请求传过来的Query参数为city: shanghai
这些开箱即用的装饰器有以下这些:
@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 |
HTTP请求方法
从上面生成的代码中的,我们可以发现除了@Get请求方法装饰器外还有一些其它的,事实上,Nest为所有标准 HTTP 方法提供了装饰器:@Get()、@Post()、@Put()、@Delete()、@Patch()、@Options()和@Head()。
一般大家常用的都是get请求与post请求吧,好像很少看到其它类型的请求
获取get请求参数
这里可以使用@Request装饰器与@Query装饰器,与express完全一致
上面已经演示了通过@Query获取,那就在通过@Request再演示一遍
// nanjiu.controller.ts
@Get()
findAll(@Request() req, @Query() query) {
console.log('find', req.query, query)
return this.nanjiuService.findAll();
}
通过req.query与Query获取的是一致的,所以使用@Query装饰器获取get类型的请求参数会更方便一些,如果你还想获取更多关于请求的参数可以使用@Request装饰器。
获取post请求参数
与express一样,可以使用@Request装饰器与Body装饰器
// nanjiu.controller.ts
@Post()
create(@Body() createNanjiuDto: CreateNanjiuDto) {
console.log('body', createNanjiuDto)
return this.nanjiuService.create(createNanjiuDto);
}
查看日志
动态路由
当需要接受动态数据作为请求的一部分(例如,GET /nanjiu/1获取带有 id 为 1的nanjiu)时,具有静态路径的路由将不起作用。为了定义带参数的路由,我们可以在路由的路径中添加路由参数**标记,以捕获请求 URL 中该位置的动态值。**下面装饰器示例中的路由参数标记@Get()演示了这种用法。以这种方式声明的路由参数可以使用装饰器来访问@Param()
// nanjiu.controller.ts
@Get(':id')
findOne(@Param() params) {
console.log('params', params)
return this.nanjiuService.findOne(+params.id);
}
查看日志
状态码
从上面几个例子我们可以看到,默认情况下响应状态码都是200,POST请求除外,POST默认为201,Nest同样提供了HttpCode()装饰器来自定义响应状态码
// nanjiu.controller.ts
@Get()
@HttpCode(202)
findAll(@Request() req, @Query() query) {
console.log('find', req, query)
return this.nanjiuService.findAll();
}
响应头
想要自定义响应头,可以使用@Header装饰器
@Post()
@Header('Cache-Control', 'none')
create(@Body() createNanjiuDto: CreateNanjiuDto) {
console.log('body', createNanjiuDto)
return this.nanjiuService.create(createNanjiuDto);
}
【NestJS系列】核心概念:Controller控制器的更多相关文章
- Spark系列-核心概念
Spark系列-初体验(数据准备篇) Spark系列-核心概念 一. Spark核心概念 Master,也就是架构图中的Cluster Manager.Spark的Master和Workder节点分别 ...
- ZooKeeper 系列(一)—— ZooKeeper核心概念详解
一.Zookeeper简介 二.Zookeeper设计目标 三.核心概念 3.1 集群角色 3.2 会话 3.3 数据节点 3.4 节点 ...
- ZooKeeper系列(一)—— ZooKeeper 简介及核心概念
一.Zookeeper简介 Zookeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护.Zookeeper 可以用于实现分布式系统中常见的发布/订阅.负载均衡.命令服务.分布式协调 ...
- Storm 系列(二)—— Storm 核心概念详解
一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的 Storm 流处理程序被称为 Storm topology(拓扑).它是一个是由 Spouts 和 Bolts 通过 Stre ...
- 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)
一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...
- Kubernetes核心概念总结
目录贴:Kubernetes学习系列 1.基础架构 1.1 Master Master节点上面主要由四个模块组成:APIServer.scheduler.controller manager.etcd ...
- 后端技术杂谈11:十分钟理解Kubernetes核心概念
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 本文转自 https://github.com/h2pl/Java-Tutorial 喜欢的 ...
- kubernetes核心概念
摘抄自: https://www.cnblogs.com/zhenyuyaodidiao/p/6500720.html 1.基础架构 1.1 Master Master节点上面主要由四个模块组成:A ...
- [转]k8s核心概念
转载自 https://blog.csdn.net/real_myth/article/details/78719244 什么是kubernetes 首先,他是一个全新的基于容器技术的分布式架构领先方 ...
- Kubernetes 核心概念
什么是Kubernetes? Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成K ...
随机推荐
- Mysql中的数据类型注意事项
整型数据类型 MySQL数据类型 含义(有符号) tinyint 1字节,范围(-128~127) smallint 2字节,范围(-32768~32767) mediumint 3字节,范围(-83 ...
- 【opencv-c++】4.1-4.2 图像和大型数组类型
4.1-4.2 图像和大型数组类型 动态可变的存储 我们将进入大型数组类型的世界,它们之中最主要的当属c v::Mat,这个结构可以视为是OpenCV所有C++实现的核心,OpenCV所有主要函数都或 ...
- VMware虚拟机---Ubuntu无法连接网络该怎么解决?
在学习使用Linux系统时,由于多数同学们的PC上多是Windows系统,故会选择使用VMware创建一个虚拟机来安装Linux系统进行学习. 安装完成之后,在使用时总是会遇到各种各样的问题.本片随笔 ...
- Go函数基础
在Go语言中,函数是一种基本的代码组织方式.函数能够接受输入参数并返回结果.Go语言中的函数有以下特点: 函数定义使用关键字func,后跟函数名.参数列表和返回值类型. 如果函数有返回值,则在函数定义 ...
- 文心一言 VS chatgpt (6)-- 算法导论2.3 1~2题
一.使用图 2-4作为模型,说明归并排序在数组 A=(3,41,52,26,38,57,9,49)上的操作. 文心一言: 使用图 2-4作为模型,说明归并排序在数组 A=(3,41,52,26,38, ...
- 园子的商业化努力-AI人才服务:招募AI导师
各位园子的小伙伴: 感谢大家对园子的支持,园子差不多接近20年的历程,一直是最低配模式生存和发展,感谢大家对于前段时间的困局给予了商业化的各种建议!在大家的鼓励与支持之下,园子的商业化努力正在以更快的 ...
- 渗透测试-struts2攻防环境搭建拿shell
一.下载Jspstudy 打开目录D:\JspStudy\tomcat\webapps 二.打开struts2并进行拿shell 1.打开struts2 在浏览器中输入网址http://localho ...
- 代码随想录算法训练营Day55 动态规划
代码随想录算法训练营 代码随想录算法训练营Day55 动态规划| 392.判断子序列 115.不同的子序 392.判断子序列 题目链接:392.判断子序列 给定字符串 s 和 t ,判断 s 是否为 ...
- Java方法的调用以及方法参数传递、方法的递归调用
一.方法的调用以及方法参数传递 1.方法的定义: 访问修饰符 返回值类型 方法名 ([参数列表]){ 方法体 } 如果方法体中需要一些未知的数据作为执行条件,那么这些数据可以作为参数. 如果方 ...
- 从 Blast2GO 本地化聊一聊 Linux 下 MySQL 的源码安装
Blast2GO 是一个基于序列相似性搜索的 GO 注释和功能分析工具,它可以直接统计分析基因功能信息,并可视化 GO 有向非循环图(DAG)上的相关功能特征,分析 BLAST.GO-mapping. ...