摘要:本文首发于用控制路由在中长这样还有上的框架两者都用来控制路由,这样写的好处是更简洁更优雅更清晰。反观或上的路由完全差了一个档次从开始就有了,只是浏览器和都还没有支持。
本文首发于:用Decorator控制Koa路由
在Spring中Controller长这样
@Controller
public class HelloController{
@RequestMapping("/hello")
String hello() {
return "Hello World";
}
}
还有Python上的Flask框架
@app.route("/hello")
def hello():
return "Hello World"
两者都用decorator来控制路由,这样写的好处是更简洁、更优雅、更清晰。
反观Express或Koa上的路由
router.get("/hello", async ctx => {
ctx.body = "Hello World"
})
完全差了一个档次
JS从ES6开始就有Decorator了,只是浏览器和Node都还没有支持。需要用babel-plugin-transform-decorators-legacy转义。
Decorator基本原理首先需要明确两个概念:
Decorator只能作用于类或类的方法上
如果一个类和类的方法都是用了Decorator,类方法的Decorator优先于类的Decorator执行
Decorator基本原理:
@Controller
class Hello{
}
// 等同于
Controller(Hello)
Controller是个普通函数,target为修饰的类或方法
// Decorator不传参
function Controller(target) {
}
// Decorator传参
function Controller(params) {
return function (target) {
}
}
如果Decorator是传参的,即使params有默认值,在调用时必须带上括号,即:
@Controller()
class Hello{
}
如何在Koa中使用Decorator
我们可以对koa-router中间件进行包装
先回顾一下koa-router基本使用方法:
var Koa = require("koa");
var Router = require("koa-router");
var app = new Koa();
var router = new Router();
router.get("/", async (ctx, next) => {
// ctx.router available
});
app
.use(router.routes())
.use(router.allowedMethods());
再想象一下最终目标
@Controller({prefix: "/hello"})
class HelloController{
@Request({url: "/", method: RequestMethod.GET})
async hello(ctx) {
ctx.body = "Hello World"
}
}
类内部方法的装饰器是优先执行的,我们需要对方法重新定义
function Request({url, method}) {
return function (target, name, descriptor) {
let fn = descriptor.value
descriptor.value = (router) => {
router[method](url, async(ctx, next) => {
await fn(ctx, next)
})
}
}
}
对RequestMethod进行格式统一
const RequestMethod = {
GET: "get",
POST: "post",
PUT: "put",
DELETE: "delete"
}
Controller装饰器需将Request方法添加到Router实例并返回Router实例
import KoaRouter from "koa-router"
function Controller({prefix}) {
let router = new KoaRouter()
if (prefix) {
router.prefix(prefix)
}
return function (target) {
let reqList = Object.getOwnPropertyDescriptors(target.prototype)
for (let v in reqList) {
// 排除类的构造方法
if (v !== "constructor") {
let fn = reqList[v].value
fn(router)
}
}
return router
}
}
至此,装饰器基本功能就完成了,基本使用方法为:
import {Controller, Request, RequestMethod} from "./decorator"
@Controller({prefix: "/hello"})
export default class HelloController{
@Request({url: "/", method: RequestMethod.GET})
async hello(ctx) {
ctx.body = "Hello World"
}
}
在App实例中同路由一样use即可。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/95612.html
摘要:注解方式为应用动态生成文档目前我司服务端应用程序框架主要采用了与,而因为今年有很多的调研阶段的产品线发布,持续部署接口文档以及线上质量监控这三个问题愈发突出。 swagger-decorator:注解方式为 Koa2 应用自动生成 Swagger 文档 从属于笔者的服务端应用程序开发与系统架构,记述了如何在以 Koa2 与 koa-router 开发服务端应用时,通过自定义 swagg...
摘要:即为装饰器函数的这里主要为了获取路由路径的前缀,为请求方法,为请求路径,为请求执行的函数。下边是设置路由路径前缀和塞入内容的装饰器函数就不多说了,就是挂载前缀路径到类的原型对象上,这里需要注意的是作用于类,所以是被修饰的类本身。 很多面对象语言中都有装饰器(Decorator)函数的概念,Javascript语言的ES7标准中也提及了Decorator,个人认为装饰器是和async/a...
摘要:前言今天闲来时看了看中的新标准之一,装饰器。过程中忽觉它和中的注解有一些类似之处,并且当前版本的中已经支持它了,所以,就动手在一个应用中尝鲜初体验了一番。另外,由于装饰器目前还是中的一个提案,其中具体细节可能还会更改。 前言 今天闲来时看了看ES7中的新标准之一,装饰器(Decorator)。过程中忽觉它和Java中的注解有一些类似之处,并且当前版本的TypeScript中已经支持它了...
摘要:中基于的自动实体类构建与接口文档生成是笔者对于开源项目的描述,对于不反感使用注解的项目中利用添加合适的实体类或者接口类注解,从而实现支持嵌套地实体类校验与生成等模型生成基于的接口文档生成等等功能。 JavaScript 中基于 swagger-decorator 的自动实体类构建与 Swagger 接口文档生成是笔者对于开源项目 swagger-decorator 的描述,对于不反感使...
摘要:最近新开了一个项目,采用来开发,在数据库及路由管理方面用了不少的装饰器,发觉这的确是一个好东西。在中的使用该装饰器会在定义前调用,如果函数有返回值,则会认为是一个新的构造函数来替代之前的构造函数。函数参数装饰器最后,还有一个用于函数参 最近新开了一个Node项目,采用TypeScript来开发,在数据库及路由管理方面用了不少的装饰器,发觉这的确是一个好东西。 装饰器是一个还处于草案中...
阅读 2538·2023-04-25 14:50
阅读 3172·2021-11-17 09:33
阅读 2796·2019-08-30 13:07
阅读 3103·2019-08-29 16:57
阅读 1161·2019-08-29 15:26
阅读 3793·2019-08-29 13:08
阅读 2211·2019-08-29 12:32
阅读 3653·2019-08-26 13:57