前言

控制器主要是用来处理客户端传入的请求并向客户端返回响应。

它一般是用来做路由导航的,内部路由机制控制哪个控制器接收哪些请求。

路由

为了创建基本控制器,我们需要使用@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 基本类型(例如,stringnumberboolean)时,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'路径将匹配abcdab_cdabecd等。字符?+*()可以在路由路径中使用,并且是其正则表达式对应项的子集。连字符 ( -) 和点 ( .) 按字面意思解释为基于字符串的路径。

请求对象

作为后端项目,访问客户端请求的详细信息也非常重要,从上面生成的代码中我们可以看到@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.queryQuery获取的是一致的,所以使用@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 为 1nanjiu)时,具有静态路径的路由将不起作用。为了定义带参数的路由,我们可以在路由的路径中添加路由参数**标记,以捕获请求 URL 中该位置的动态值。**下面装饰器示例中的路由参数标记@Get()演示了这种用法。以这种方式声明的路由参数可以使用装饰器来访问@Param()

// nanjiu.controller.ts
@Get(':id')
findOne(@Param() params) {
console.log('params', params)
return this.nanjiuService.findOne(+params.id);
}

查看日志

状态码

从上面几个例子我们可以看到,默认情况下响应状态码都是200POST请求除外,POST默认为201Nest同样提供了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控制器的更多相关文章

  1. Spark系列-核心概念

    Spark系列-初体验(数据准备篇) Spark系列-核心概念 一. Spark核心概念 Master,也就是架构图中的Cluster Manager.Spark的Master和Workder节点分别 ...

  2. ZooKeeper 系列(一)—— ZooKeeper核心概念详解

    一.Zookeeper简介 二.Zookeeper设计目标 三.核心概念         3.1 集群角色         3.2 会话         3.3 数据节点         3.4 节点 ...

  3. ZooKeeper系列(一)—— ZooKeeper 简介及核心概念

    一.Zookeeper简介 Zookeeper 是一个开源的分布式协调服务,目前由 Apache 进行维护.Zookeeper 可以用于实现分布式系统中常见的发布/订阅.负载均衡.命令服务.分布式协调 ...

  4. Storm 系列(二)—— Storm 核心概念详解

    一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的 Storm 流处理程序被称为 Storm topology(拓扑).它是一个是由 Spouts 和 Bolts 通过 Stre ...

  5. 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)

    一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...

  6. Kubernetes核心概念总结

    目录贴:Kubernetes学习系列 1.基础架构 1.1 Master Master节点上面主要由四个模块组成:APIServer.scheduler.controller manager.etcd ...

  7. 后端技术杂谈11:十分钟理解Kubernetes核心概念

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 本文转自 https://github.com/h2pl/Java-Tutorial 喜欢的 ...

  8. kubernetes核心概念

    摘抄自:  https://www.cnblogs.com/zhenyuyaodidiao/p/6500720.html 1.基础架构 1.1 Master Master节点上面主要由四个模块组成:A ...

  9. [转]k8s核心概念

    转载自 https://blog.csdn.net/real_myth/article/details/78719244 什么是kubernetes 首先,他是一个全新的基于容器技术的分布式架构领先方 ...

  10. Kubernetes 核心概念

    什么是Kubernetes? Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成K ...

随机推荐

  1. XMake学习笔记(1):Windows(MSYS2)下MinGW-w64环境搭建和XMake安装

    以前写的C++基本都是C with STL,大多是面向过程的算法题,或者比较小的项目,然后经常报各种编译错误(对编译原理不熟),经常把人搞到崩溃,搞不懂构建.链接之类的东西. 现在开始记录一下XMak ...

  2. iframe分栏拖拽伸缩例子

    这个标题有些绕口,鄙人愚笨,实在找不到一个比较准确的说法,总之就是: 一个页面内显示多个iframe,一个变宽,另一个就变窄,一个变高,另一个就变矮的这种可自由伸缩的效果.它们之间有一个可多拽的分隔条 ...

  3. #PowerBi 1分钟学会,以“万”为单位显示数据

    PowerBi是一款强大的数据分析和可视化工具,它可以帮助我们快速地制作出各种图表和报表,展示数据的价值和洞察. 但是,有时候我们的数据量太大,导致图表上的数字难以阅读和比较.例如,如果我们想要查看某 ...

  4. #Powerquery 数据结构基础 一维数据与二维数据

    本文参考了采悟老师的文章,推荐大家看原文,本文为笔记随笔 https://mp.weixin.qq.com/s?__biz=MzA4MzQwMjY4MA==&mid=2484068871&am ...

  5. React Hooks方法

    1.useState import React, { useState } from "react"; /* 目标: 掌握useState的使用 作用:实现响应式数据的 用法:引入 ...

  6. Django-账号用户密码修改

    Django账号密码修改命令: python manage.py changepassword python manage.py changepassword 实操分析: 第一次修改失败是因为违反了密 ...

  7. ComboBox1 绑定手动创建的DataTable

    '************************************************** '*过程名称:DT_PAFORMAL '*功能说明:员工类别 '**************** ...

  8. 深入理解 python 虚拟机:破解核心魔法——反序列化 pyc 文件

    深入理解 python 虚拟机:破解核心魔法--反序列化 pyc 文件 在前面的文章当中我们详细的对于 pyc 文件的结构进行了分析,pyc 文件主要有下面的四个部分组成:魔术. Bite Filed ...

  9. 一文教会你用Apache SeaTunnel Zeta离线把数据从MySQL同步到StarRocks

    在上一篇文章中,我们介绍了如何下载安装部署SeaTunnel Zeta服务(3分钟部署SeaTunnel Zeta单节点Standalone模式环境),接下来我们介绍一下SeaTunnel支持的第一个 ...

  10. .net开发者应掌握的利器CommunityToolkit.HighPerformance——MemoryOwner与SpanOwner

    MemoryOwner和SpanOwner都可以理解为是对ArrayPool<>的一个包装,无非一个是在堆栈上,一个是在托管堆上.既然做了包装,那肯定随之而来就是改进和优化. 目录 Mem ...