express-路由自动加载

在express构建的程序中,配置一个路由规则可以用 app.get(urlPath, callback) 方式,也可以用路由中间件 app.use(urlPath, express.Router),但是在项目扩大时候这种配置会显得很冗余,所以就需要实现一种路由自动加载的机制。

1.项目目录与路由规则映射

自动加载路由的原理就是找出控制器的目录结构和路由规则的匹配关系,比如请求/ 就是对应控制器的根目录,那么请求/home/api 就是对应下面的目录结构:
在这里插入图片描述
而请求的url路径的最后一个块可以当成是这个控制器的一个导出的方法,比如/home/api/getlunbo对应如下:
在这里插入图片描述

注意的是index 可以省略,也就是说访问/home/api/ 就是相当于访问 index 方法

2.构建控制器对象的配置

如果我们只是单纯的把控制器对象导出的方法都搞成一个function,那么对于类似 /member/list/:id 这种路由规则就无法绑定。所以我们可以考虑导出一个object,在这个对象配置一个属性。比如:params 表示所有占位参数数据,method表示请求的方法,handler 表示对应的处理函数,如下:
在这里插入图片描述

3.自动加载函数

自动加载函数用到glob模块来同步读取控制器下面的文件,根据目录结构和配置对象参数来构造出路由中的路径,绑定对应的handler

const glob = require('glob');

function autoLoad(app, root) {

    // 同步读取root目录下的所有js文件
    glob.sync(`${root}/**/*.js`).forEach((file) => {

        // 利用控制器目录结构构和方法构建路由url
        let filePath = file.replace(/\.[^.]*$/, '');
        let controller = require(file);
        let urlPath = filePath.replace(root, '').replace(/\/index$/, '');
        let methods = Object.keys(controller);

        function applyMethod(name, methodBody) {
            let body = methodBody;
            let routeURL = urlPath + (name === 'index' ?  '' : `/${name}`);
            let method = 'get';
            let handler;
            let params;

            switch(typeof body) {
                case 'function':
                    handler = body;
                    break;
                case 'object':
                    params = body.params || [];
                    method = (body.method || 'get').toLowerCase();
                    routeURL = routeURL + '/' + params.join('/');
                    handler = body.handler;
                    break;
                default: return;
            }

            // 绑定路由规则
            app[method](routeURL, handler);
            // 这里兼容访问index的情况
            if(name === 'index') {
                app[method](routeURL + '/index', handler);
            }
        }

        methods.forEach(function(method){
            let methodName = method;
            let methodBody = controller[method];

            applyMethod(methodName, methodBody);
        });
    });
}

module.exports = autoLoad;

在入口处导入并调用:

const express = require('express')
const path = require('path')
const autoLoadRouter = require('./routes/autoLoad')

let app = express()
autoLoadRouter(app, path.join(__dirname, 'controller'))
4.配置参数扩展
  • 考虑到某些控制器不需要配置路由规则,我们可以增加一个排除的控制器路径数组。
  • 另外某些路由需要中间件处理,我们可以增加一个中间件函数数组,在函数里面调用next()依次执行中间件,最后才调用我们的handler
  • 增加一个重写url规则的配置,绑定重写后的url规则即可

具体的修改参考:
https://github.com/SFantasy/express-load-router

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值