最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

利用Decorator如何控制Koa路由详解

来源:动视网 责编:小采 时间:2020-11-27 22:12:30
文档

利用Decorator如何控制Koa路由详解

利用Decorator如何控制Koa路由详解:前言 在Spring中Controller长这样 @Controller public class HelloController{ @RequestMapping(/hello) String hello() { return Hello World; } } 还有Python上的Flask框架 @app.route(/hello)
推荐度:
导读利用Decorator如何控制Koa路由详解:前言 在Spring中Controller长这样 @Controller public class HelloController{ @RequestMapping(/hello) String hello() { return Hello World; } } 还有Python上的Flask框架 @app.route(/hello)


前言

在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即可。

    总结

    文档

    利用Decorator如何控制Koa路由详解

    利用Decorator如何控制Koa路由详解:前言 在Spring中Controller长这样 @Controller public class HelloController{ @RequestMapping(/hello) String hello() { return Hello World; } } 还有Python上的Flask框架 @app.route(/hello)
    推荐度:
    标签: 路由 Koa decorator
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top