首页 > 其他分享 >【前端学习】 NestJS 之 控制器 (Controller)

【前端学习】 NestJS 之 控制器 (Controller)

时间:2024-09-26 14:49:54浏览次数:10  
标签:控制器 return 请求 dogs Controller NestJS id 路由 string

文章目录

控制器 (Controller)

控制器负责处理传入请求向客户端返回响应

控制器的目的是接收应用的特定请求。路由机制控制哪个控制器接收哪些请求。通常,每个控制器都有不止一条路由,不同的路由可以执行不同的操作。

为了创建基本控制器,我们会使用到装饰器。装饰器将类与所需的元数据相关联,并使 Nest 能够创建路由映射(将请求绑定到相应的控制器)。

*路由 (router)

接下来我们会使用@Controller()装饰器,这是定义基本控制器所必需的。在@Controller()装饰器中使用路径前缀可以让我们轻松地对一组相关路由进行分组,并最大限度地减少重复代码。

我们可以将一组路由分组,它们的管理与路由/dogs下的狗实体交互。这样的话,就不必为文件中的每个路由重复该部分路径。

首先在src目录下创建一个名为dogs的文件夹;随后在dogs文件夹内创建一个名为dogs.controller.ts文件:

创建文件

注意: 你也可以不需要遵循如此严格的目录格式。你可以在 命令行 中输入 nest g controller [name] 命令来通过CLI 创建对应的控制器 (此处的name 为dogs ) 。随后找到你的dogs.controller.ts文件:

/* dogs.controller.ts */
import { Controller, Get } from '@nestjs/common';

@Controller('dogs')
export class DogsController {
	@Get()
	findAll(): string {
		return 'This action will return all dogs!';
	}
}

为了保证代码的阅读性,就不在代码内添加注释了,在下面为读者逐一讲解:

  • @Controller('dogs'):小括号内的 'dogs' 便是我们的路由, 即/dogs

  • @Get():此装饰器对应的就是我们HTTP 对应的请求方法,你同样可以在内部声明一个前缀,比如@Get('name'),这样的组合会为像GET /dogs/name 这样的请求生成路由映射;

  • findAll():这个方法名称是我们自己定义的,声明的名称足够语义化就可以。

请求对象 (request object)

处理程序通常需要访问客户端请求的详细信息。我们可以通过将@Req()装饰器添加到处理程序的签名来指示Nest 注入它来访问请求对象。

此处会在我们上面的代码基础之上,添加一些内容来达成访问客户端请求的详细信息的功能。

/* dogs.controller.ts */
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('dogs')
export class DogsController {
	@Get()
	findAll(@Req() request: Request): string {
		return 'This action will return all dogs!';
	}
}

注意上方添加的点:

  • 首先是import的导入内容变多了,此内容一般不需要我们手动添加,当你使用时会自动添加;

  • @Req()装饰器是写在了findAll( ) 方法的参数内部的。

*资源 (Resources)

这里直白的说,GET 路由就是用来获取 dogs资源的,专业一点叫定义了一个端点;那通常还会提供一个创建新记录的端点。所以接下来我们来创建POST 处理程序:

仍然在dogs.controller.ts文件中,但是注意,下方的代码并没有做上方的添加@Req()装饰器的功能,而是基于第一段代码:

/* dogs.controller.ts */
import { Controller, Get, Post } from '@nestjs/common';

@Controller('dogs')
export class DogsController {
	@Post()
	create(): string {
		return `This action will add a new dog.`;
	}

	@Get()
	findAll(): string {
		return `This action will return all dogs!`;
	}
}

所以这一步其实不难对么?Nest 为所有标准的HTTP 方法提供了装饰器:@Get()@Post()@Put()@Delete()@Patch()@Options()@Head()。此外,@All() 定义了一个端点来处理所有的HTTP 方法

状态码 (status code)

默认情况下,响应状态代码为200 (除了POST 请求的代码为 201) 。通过在处理程序级别添加@HttpCode(...) 装饰器来轻松更改此行为。

简单的例子:

import { HttpCode } from '@nestjs/common';

@Post()
@HttpCode(204)
create(): string {
	return `This action will add a new dog`;
}

标头 & 重定向 (headers & redirection)

要指定自定义响应标头,可以通过Header()装饰器;要将响应重定向到特定的URL ,可以使用@Redirect() 装饰器:

其中@Redirect()有两个参数,为urlstatusCode,均为可选。如果省略的话则statusCode的默认值为302

下方是两个简单的例子:

/* 标头 */
@Post()
@Header('Cache-Control', 'none')
create() {
	return `This action will add a new dog.`;
}

/* 重定向 */
@Get()
@Redirect('URL', 301)

*路由参数 (route parameters)

当你需要接受动态数据作为请求的一部分时 (例如,GET /dogs/1 获取ID 为1 的dog) ,具有静态路径的路由将不起作用。为了定义带参数的路由,我们可以在路由的路径中添加路由参数标记,以捕获请求 URL 中该位置的动态值。此时可以使用@Param()装饰器。

下面的代码我们会对上面书写的@Get()部分代码进行一下修改:

@Get(':id')
findOne(@Param() params: any): string {
	console.log(params.id);
	return `This action will return a #${param.id} dog.`;
}

@Param()用于修饰方法参数,并使路由参数可用作方法体内该修饰方法参数的属性。例如像上方的代码,通过引用params.id来访问id参数。

当然也可以像下面的方法来传入一个特定的参数token给装饰器,然后在方法体中直接通过名称引用路由参数:

@Get(':id')
findOne(@Param('id') id: string): string {
	return `This action will return a #${id} dog.`;
}

*请求负载 (request payloads)

上方我们的 POST 路由处理程序不接受任何客户端参数。在这里我们会通过添加@Body()装饰器来解决此问题。

在这里先科普一句DTO (数据传输对象) 架构。DTO 是定义数据如何通过网络发送的对象。

接下来让我们创建CreateDogDto类,注意,此处为一个新的文件,同样创建在dogs目录下,文件名为create-dog.dto.ts

/* create-dog.dto.ts */
export class CreateDogDto {
	name: string;
	age: number;
	bark: string;
}

当我们创建完成后,就可以在DogsController 中使用新创建的DTO 了:

/* dogs.controller.ts */
// ...
@Post()
async create(@Body() createDogDto: CreateDogDto) {
	return `This action will add a new dog.`;
}
// ...

在这里说一句人话,其实 请求负载 它还有一个名字就是我们的 请求体 ,发送POST 请求时所携带的参数均会放在这个请求体中。

接下来让我们来补全剩下的两个常用HTTP请求吧 ( PUT & DELETE ):

/* dogs.controller.ts */
/* 本代码块 会展示该文件目前 所有的代码 */

import { Body, Controller, Delete, Get, Param, Post, Put } from "@nestjs/common";
import { CreateDogDto } from "./dto/create-dog.dto";
import { UpdateDogDto } from "./dto/update-dog.dto";

@Controller('dogs')
export class DogsController {
    @Post()
    async create(@Body() createDogDto: CreateDogDto) {
        return `This action will create a new dog!`;
    }

    @Get()
    findAll(): string {
        return `This action will return all dogs!`;
    }

    @Get(':id')
    findOne(@Param() params: any): string {
        return `This action will return a #${params.id} dog!`;
    }

    @Put(':id')
    update(@Param('id') id: string, @Body() updateDogDto: UpdateDogDto): string {
        return `This action will update #${id} dog.`;
    }

    @Delete(':id')
    remove(@Param('id') id: string): string {
        return `This action will remove #${id} dog.`;
    }
}

此时可以看一下我们src目录下的结构:

src 的目录结构

启动并运行

虽然我们已经完全定义了上述的控制器 (Controller ),但是 Nest 不知道DogsController的存在,所以不会创建此类的实例。

这是因为:控制器始终属于一个模块,这也是我们在@Module()装饰器中包含controllers数组的原因。因为还没有定义除根AppMoudule之外的任何其他模块。所以接下来的操作是引入:

/* app.module.ts */
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DogsController } from './dogs/dogs.controller';

@Module({
  imports: [],
  // 在controllers 数组内部添加我们的控制器 DogsController
  controllers: [AppController, DogsController],
  providers: [AppService],
})
export class AppModule {}

通过使用 @Module()装饰器 将元数据附加到模块类,Nest 现在可以轻松反映必须安装哪些控制器。

现在你便可以在浏览器内测试你的GET 请求了。

如下图:

GET 全部请求结果

附带id 的GET 请求结果:
GET 附带id 的请求结果

为什么我要说测试GET 请求?其他的不行吗?

不行。

所以这里大家可以下载一个ApiFox,在其内部可以轻松创建快捷请求。在这里便给大家截几张图示范一下:

POST 请求:

POST 请求结果

PUT 请求:

PUT 请求结果

DELETE 请求:

DELETE 请求结果

小结

以上便是控制器一些最基本的概念和知识了。上文的代码也均已经测试过,可以跑通。通过最简单的例子来逐步学习知识也是一个非常好的方法。如果有不同见解和其他想法,很欢迎来交流和沟通!

标签:控制器,return,请求,dogs,Controller,NestJS,id,路由,string
From: https://blog.csdn.net/LZwarning0215/article/details/142555364

相关文章

  • nav2的behavior模块,controller模块,lifecycle_manager模块
    Navigation2-main项目中nav2_behaviors、controller和lifecycle_manager文件夹的源代码详解在前述章节中,我们已经详细介绍了constrained_smoother、collision_monitor、mppi_controller、dwb_controller、rotation_shim和core模块。本节将继续介绍navigation2-ma......
  • 【Java】@RestController 和@Controller的区别
    二者都是定义控制器的注解,它们的区别如下:(1)返回值不同。@RestController注解相当于@Controller和@ResponseBody的结合。其中,@ResponseBody是一个针对方法返回值进行处理的注解,处理后的RestController注解会将所有处理请求的方法默认解析为将方法返回值直接作为响应体内容返回,......
  • <<编码>> 第 17 章 自动操作(3)--带控制器的自动加法器 示例电路
    info::操作说明操作说明:计数器处,因16位过于庞大,这里只使用5位代替首先按左边的清零.接着可以自行使用TO置高位并手动更改地址的值检查代码及数据的值(可选,这些值已提前置入)完毕后确保已将两TO值置为低位.之后,单击手动瞬时开关模拟时钟信号驱动计......
  • k8s Ingress和 Ingress Controller
    一、Ingress和IngressController概述关于service四层代理介绍链接点我跳转1.1Ingressingress是k8s中的资源,主要是管理ingress-controller这个代理的配置文件。Ingress是对集群中服务的外部访问进行管理的API对象,典型的访问方式是HTTP,Ingress可以提供负载均衡、SSL终结和基......
  • 揭秘 ARMxy 嵌入式控制器的 ModbusTCP 通信协议实战案例
    引言随着工业4.0概念的普及,越来越多的企业开始寻求将传统设备与现代信息技术相融合的方法,以提升生产效率和管理水平。在这个过程中,ModbusTCP作为一种成熟的工业通信协议,因其简单易用、兼容性好而在工业自动化领域得到广泛应用。与此同时,Node-Red作为一种开放源码的可视化编程工具,......
  • SY5072BABT 单相过渡模式PFC控制器
    SY5072B为恒压过渡模式带功率因数校正(PFC)的升压控制器函数。常开时间控制应用于实现高PF和低THD,无需乘法器。它以准谐振模式驱动升压变换器高效率和更好的电磁干扰性能。它采用特殊设计,实现快速启动、快速运行可靠的安全保护要求。•谷开通,实现低开关损耗轻载时......
  • 【EasyBlog】基于React+AntD+NextJS+NestJS+MySQL打造的开源博客系统
    Github项目地址:https://github.com/fecommunity/easy-blog,欢迎Star。Easy-BlogEasy-Blog是一套集成文章发表、页面创建、知识库管理、博客后台管理等功能于一体的博客系统。首页-浅色主题首页-暗黑主题文章阅读后台管理✨特性......
  • asp.net webapi 控制器中获取appsettings.json 中的数组对象
    appsettings.json文件内容: {"Logging":{"LogLevel":{"Default":"Information","Microsoft.AspNetCore":"Warning"}},"MyConfigKey":"MyConfigValue"......
  • 剖析嵌入式控制器,为何推荐 ARMxy?
    嵌入式ARM控制器是一种基于ARM架构的嵌入式系统控制器,广泛应用于各种嵌入式系统中,包括工业物联网关、边缘计算网关、智慧城市、智能设备、工业自动化等领域。嵌入式ARM控制器具有高性能、低功耗、强大的多任务处理能力等特点,成为嵌入式系统的核心处理器之一。ARMxy系列ARM嵌入式控......
  • 解读嵌入式控制器和 PLC 区别的关键密码
    嵌入式控制器和PLC(可编程逻辑控制器)主要在应用领域、开发难度、编程语言和实时性方面存在显著差异。具体分析如下:1、应用领域和规模: 嵌入式控制器通常用于小型、低功耗、低成本的控制系统,如智能家居、智能医疗设备等。而PLC则主要用于工业自动化控制系统中,处理复杂逻辑控制和高稳......