【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理函数装饰器注册篇(5/8)【controller+action】

简介: 文章目录前情概要上篇文章把action的注册讲完了,但是我们的处理函数没有指定可接受的httpmethod,也没有别名上面的。下面我们使用typescript的特性之一装饰器来实现一把这个特性。在控制器和处理函数的注册篇中有说到的第三,第四个参数就在这里排上用场拉。

文章目录

前情概要

上篇文章把action的注册讲完了,但是我们的处理函数没有指定可接受的httpmethod,也没有别名上面的。下面我们使用typescript的特性之一装饰器来实现一把这个特性。

在控制器和处理函数的注册篇中有说到的第三,第四个参数就在这里排上用场拉。
SetActionDescriptor(cName, aName, undefined, undefined, _reg_controller_name, cType, aType)//加入缓存
第三个参数[httpMethod] 请求方法类型。默认给undefined,后续再通过扫描action上面的特性标签增加进来
第四个参数 [actionName] 路由action名字。默认给undefined,后续再通过扫描action上面的特性标签增加进来

get,post,actionname的装饰器实现方式

代码非常简单,通过SetActionDescriptor函数对当前的action的某些属性进行重写。

typescript的装饰器目前来说还是一个实验性的功能,依照微软的尿性,应该也没变动了,就算有也是增加新功能新特性。
然后装饰器这玩意和后端语言的比如dotnet的特性(attribute)、java的标注等比较相似。可以给方法增加一些额外的数据等。具体,可查看typescript 装饰器参考文档

import { SetActionDescriptor } from './RouteFactory';
import { ActionParamDescriptor, SetActionParamDescriptor, parameterFromType } from './RouteHandler';
/**
 * 标记当前方法只接受post请求
 * 
 * @export
 * @returns 
 */
export function post() {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        SetActionDescriptor(target.constructor.name, propertyKey, 'post')
    }
}
/**
 * 标记当前方法只接受get请求
 * 
 * @export
 * @returns 
 */
export function get() {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        SetActionDescriptor(target.constructor.name, propertyKey, 'get')
    }
}
/**
 * 重写当前方法的名字,请求使用重写后的名字进行调用
 * 
 * @export
 * @param {string} actionName 
 * @returns 
 */
export function actionName(actionName: string) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        SetActionDescriptor(target.constructor.name, propertyKey, undefined, actionName)
    }
}

装饰器使用列子

觉不觉得眼熟?是不是和C#、java里面的特性、标注差不多。

//HostController.ts
import { BaseController, get, post, auth, actionName, ViewResult } from "gd-express-basic";

export class HostController extends BaseController {
    @get()
    public index() {
        return this.view("hostIndex", {});
    }
    @auth()
    @post()
    @actionName("saveHost")
    public hostAdd() {
        return this.view("hostAdd", {});
    }
}

装饰器的基本原理

HostController.ts 为typescript源文件代码。
HostController.js为使用tsc编译为es6后的代码。

//HostController.js
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
//decorators 就是我们声明的装饰器返回的处理闭包函数啦
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    //d(target, key, r) ,调用函数,实际上就是return function (target: any, propertyKey: string, descriptor: PropertyDescriptor)调用这里返回的这个function。
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
const gd_express_basic_1 = require("gd-express-basic");
class HostController extends gd_express_basic_1.BaseController {
    index() {
        return this.view("hostIndex", {});
    }
    hostAdd() {
        return this.view("hostAdd", {});
    }
}
// 1.执行__decorate函数
__decorate([
    gd_express_basic_1.get(),//调用我们声明的装饰器,返回要处理函数(闭包)
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], HostController.prototype, "index", null);
__decorate([
    gd_express_basic_1.auth(),
    gd_express_basic_1.post(),
    gd_express_basic_1.actionName("saveHost"),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], HostController.prototype, "hostAdd", null);
exports.HostController = HostController;
//# sourceMappingURL=HostController.js.map

简单来说就是在源文件加载的时候执行一次__decorate函数,__decorate函数内可以简单理解为调用我们的声明的装饰器函数返回的闭包函数。

到此,我们的controller和action的发现和配置基本上算完成了。

目录
相关文章
|
4月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
4月前
|
前端开发 Java
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
文章介绍了如何使用SpringBoot创建简单的后端服务器来处理HTTP请求,包括建立连接、编写Controller处理请求,并返回响应给前端或网址。
79 0
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
|
5月前
|
小程序 PHP
微信小程序给 thinkphp后端发送请求出现错误 Wrong number of segments 问题的解决 【踩坑记录】
本文记录了微信小程序向ThinkPHP后端发送请求时出现"Wrong number of segments"错误的解决方法。问题原因是小程序请求header中的token变量名写错,导致token未正确传递至后端。作者提供了详细的检查步骤和建议,包括验证URL路径、参数规范和路由配置的匹配,以确保请求能正确发送和处理。
|
5月前
|
JSON JavaScript 前端开发
js请求后端9
js请求后端9
55 2
|
6月前
|
小程序 安全
Fiddler抓取小程序后端请求导入AppScan扫描快捷方法
【8月更文挑战第26天】这是一种利用 Fiddler 捕获小程序后端请求并导入 AppScan 进行安全扫描的方法。首先安装配置 Fiddler 并设置手机代理,通过 Fiddler 捕获请求;接着导出这些请求为 .saz 文件,并在 AppScan 中导入此文件,配置扫描参数后启动扫描以检测安全漏洞。操作时需确保有合法授权并遵循相关法规。尽管不同版本软件操作细节可能有所不同,但整体流程类似。
235 1
|
6月前
|
API
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
|
6月前
|
存储 缓存 移动开发
不来看一看HTML请求后端性能优化的实战总结吗?
本文主要总结了在ICBU的核心沟通场景下服务端在此次性能优化过程中做的工作,供大家参考讨论。
|
6月前
|
开发框架 缓存 .NET
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
275 0
|
6月前
|
缓存 前端开发 中间件
[go 面试] 前端请求到后端API的中间件流程解析
[go 面试] 前端请求到后端API的中间件流程解析
|
7月前
|
存储 资源调度 前端开发
JavaScript 使用axios库发送 post请求给后端, 给定base64格式的字符串数据和一些其他参数, 使用表单方式提交, 并使用onUploadProgress显示进度
使用 Axios 发送包含 Base64 数据和其他参数的 POST 请求时,可以通过 `onUploadProgress` 监听上传进度。由于整个请求体被视为一个单元,所以进度可能不够精确,但可以模拟进度反馈。前端示例代码展示如何创建一个包含 Base64 图片数据和额外参数的 `FormData` 对象,并在上传时更新进度条。后端使用如 Express 和 Multer 可处理 Base64 数据。注意,实际进度可能不如文件上传精确,显示简单加载状态可能更合适。

热门文章

最新文章