在 Express 中对路线进行分组

Posted

技术标签:

【中文标题】在 Express 中对路线进行分组【英文标题】:Grouping routes in Express 【发布时间】:2016-12-18 01:25:28 【问题描述】:

我们可以在 Laravel 中像这样对我们的路线进行分组:

Route::group("admin", ["middleware" => ["isAdmin"]], function () 

     Route::get("/", "AdminController@index");
     Route::post("/post", ["middleware" => "csrf", "uses" => "AdminController@index");

);

基本上,admin 组中定义的所有路由都会自动获取isAdmin 中间件和组名。例如,post 端点监听 admin/post 而不是 /post

有没有办法用 Express 做同样的事情?这太棒了,因为我的 Laravel 路线过去很干净,而我的 Express 路线有点混乱/重复。

这是我目前在 Express 上的 routes.js。

app.get("/admin", [passportConfig.isAuthenticated, passportConfig.isAdmin], AdminController.index);
app.post("/admin", [passportConfig.isAuthenticated, passportConfig.isAdmin], AdminController.postIndex);

谢谢。

【问题讨论】:

你用的是什么版本的快递 expressjs.com/en/4x/api.html#router 【参考方案1】:

您可以使用app.use() - https://expressjs.com/en/guide/using-middleware.html#middleware.application

app.use("/admin",[passportConfig.isAuthenticated, passportConfig.isAdmin],AdminController)


// AdminController:
var express = require('express');
var router = express.Router();
router.get('/', AdminController.index);
// etc...
module.exports = router

https://expressjs.com/en/guide/routing.html#express-router

【讨论】:

我需要为每个端点定义单独的路由器实例吗?例如 /moderator 的 var router2,例如?另外,我可以在 pastebin.com/Pj3vFdGq 这样的闭包上执行此操作,以便正确缩进/包装闭包吗?【参考方案2】:

只在你想要做的每个组中使用 before:

app.use('/admin', AdminMiddleware);
app.get('/admin/route1', ... 
app.get('/admin/route2', ... 

app.use('/user', UserMiddleware);
app.get('/user/route1', ...
app.get('/user/route2', ...

【讨论】:

【参考方案3】:
var app = require('express');
require('express-group-routes');

app.group("/api/v1", (router) => 
    router.get("/login", loginController.store); // /api/v1/login 
);

如果您不想添加前缀但仍需要对某些路由进行分组,您可以保留第一个参数并直接使用该功能:

 var app = require('express');
require('express-group-routes');

app.group((router) => 
    router.use(middleware);
);

【讨论】:

express-group-routes 不起作用。我收到以下错误“app.group 不是函数”。你能解决这个问题吗?【参考方案4】:

我刚刚写了这个模块来解决你的问题:https://github.com/benjamin658/express-inject-middleware

您可以将中间件分组为一个数组并将其传递给 express-inject-middleware...

例如:

import express from 'express';
import  injectMiddleware  from 'express-inject-middleware';

const app = express();

const authMiddleware = (req, res, next) => 
  // some auth logic...
;

const fooMiddleware = (req, res, next) => 
  // some foo logic


const barMiddleware = (req, res, next) => 
  // some bar logic


app.use(injectMiddleware(
  [
    authMiddleware,
    fooMiddleware,
  ],
  [
    // Passing the app.[METHOD] as the parameter.
    app.get('/secrets', (req, res, next) => res.send('secrets'));

    // Mount barMiddleware itself
    app.post('/secrets', barMiddleware, (req, res, next) => res.send('ok'));
  ],
));

结果如下:

app.get('/secrets', authMiddleware, fooMiddleware, (req, res, next) => res.send('secrets'));
app.post('/secrets', authMiddleware, fooMiddleware, barMiddleware, (req, res, next) => res.send('ok'));

【讨论】:

【参考方案5】:

从 express 4 开始,您可以定义和组合路由器

const app = require('express');
const adminRouter = app.Router();

adminRouter.use(isAdmin);
adminRouter.get('/', admin.index); /* will resolve to /admin */
adminRouter.post('/post', csrf, admin.index); /* will resolve to /admin/post */

app.use('/admin', adminRouter); 

希望有帮助!

【讨论】:

但是如何将中间件添加到一堆..? 在上面的示例中,isAdmincsrf 将是中间件。这能回答你的问题吗?【参考方案6】:

我找到了一些更好的解决方案,您可以按照这种方法进行操作,效果很好

路由文件route/user.js

var express = require('express')
var router = express.Router()
const authMiddleware = require('../middleware/auth')

express.application.prefix = express.Router.prefix = function(path, middleware, configure) 
    configure(router);
    this.use(path, middleware, router);
    return router;



router.prefix('/user', authMiddleware, async function (user) 
    user.route('/details').get(function(req, res) 
        res.status(201).send('Hello this is my personal details')
    ); //also you can use controller method if you have any
);

module.exports = router //make sure you have to import/use this route in main/server js

【讨论】:

【参考方案7】:

在快递 4 中对您的路线进行分组,您应该进行一些更改:

在多个文件中单独的路由文件,如adminfront 将路由器传递给routes/index.js文件中的分割路由文件
const express = require('express')
require('express-group-routes');
const router = express.Router()

require('./admin/web.router')(router)
require('./front/web.router')(router)

module.exports = router
我们可以在每个文件中使用组、中间件和前缀,如下所示
const adminPrefix = 'admin'
module.exports = function (router) 
    router.use(`\$adminPrefix`, [ adminMiddleware ]);
    router.group(`/$adminPrefix`, (router) => 
        router.get('/', home.index)
    );

【讨论】:

以上是关于在 Express 中对路线进行分组的主要内容,如果未能解决你的问题,请参考以下文章

在 VS2010 express 中对 vb.net 进行单元测试

Express + JWT 排除某些路线

Express - 路线分隔方法

express + nodeJS上的404错误,在正常路线上

使用 JWT 保护 Express 路线

如何在 Express 中获取所有已注册的路线?