Node.js 自定义路由

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013003052/article/details/78441009

介绍

在app.js 文件里,常用的为路由提供请求的 URL为这样

app.use('/index', require('../index.js')) 

如果项目变得越来越大,并且,app端的请求端口也迭代很多版本,从v1.0升级到了v5.0。那么,很容易会导致app.js臃肿并且难为维护。
到最后,你的app.js 可能会变成这样:

app.use('/v1_0/index', require('../index1.js'))
app.use('/v1_1/index', require('../index2.js'))
app.use('/v1_2/index', require('../index3.js'))
... 此处省略47行
app.use('/v5_0/index', require('../index50.js'))

那么,怎么优化这个结构呢?
建立Node.js 的路由表,将业务逻辑都放在controller中,所有复用的版本方法都指向同一个controller中的方法。

在index.js文件里,常用的结构如此

const express = require('express');
const router = express.Router();

router.get('/', async (req, res, next) => {
    res.render('index');
});

module.exports = router;

可以看到,app.use() 使用的require(‘../index1.js’),实际上是导出的router对象。
那么,我们是否可以自己定下路由表规则,去编写router对象的get/post等等过程,最后将该router导出给app.js。


1. 编写router路由表

创建router.js 在routers目录下

'use strict';
/**
 * 定义全局路由表
 * Created by davidqin on 2017/11/1.
 */

module.exports = {

  /**
   * admin管理
   */
  '/admin': {},
  /**
   * 后台运营管理
   * 请求路径:/operation/post_article/categories-add
   * 请求方法:post
   * 控制器名称:article_controller
   * 对应的控制器方法:addCategories
   */
  '/operation': {
    '/post_article':[
      '/categories-add.post.article_controller.addCategories',
      '/categories-list.get.article_controller.getCategories',
      '/categories-delete.delete.article_controller.deleteCategories',
      '/categories-edit.put.article_controller.editCategories',
      '/author-add.post.article_controller.addAuthor',
      '/author-delete.delete.article_controller.deleteAuthor',
      '/author-edit.put.article_controller.editAuthor',
      '/author-password.put.article_controller.editAuthorPassword',
      '/author-fetch.get.article_controller.fetchAuthor',
      '/author-list.get.article_controller.listAuthor',
      '/articles-list.get.article_controller.listArticles',
      '/article-detail.get.article_controller.detailArticle',
      '/article-add.post.article_controller.addArticle',
      '/article-edit.put.article_controller.editArticle',
      '/article-delete.delete.article_controller.deleteArticle',
    ],
    '/article_comment':[
      '/list.get.article_comment_controller.listComments',
      '/add.post.article_comment_controller.addComment',
      '/delete.delete.article_comment_controller.deleteComment'
    ]
  },

  /**
   * APP v1.1 API  
   */
  '/v1_1':{
    '/wikis':[
      '/list.post.article_controller.listArticles',
      '/detail.post.article_controller.detailArticle'
    ],
    '/wiki-comment':[
      '/add.post.article_comment_controller.addComment',
      '/list.get.article_comment_controller.listComments',
      '/delete.post.article_comment_controller.deleteComment'
    ],
    '/timeday':[
      '/list.get.timeday_controller.listTimeday',
      '/delete.post.timeday_controller.deleteTimeday',
      '/add.post.timeday_controller.addTimeday'
    ]
  }
};

2. 路由表解析

创建了路由表之后,最重要的是如何把路由表中的信息,解析出来,并且给router对象使用。最终导出router对象。

创建router_map.js 在routers目录下

'use strict';
/**
 * 自动根据全局路由表,require controller控制器-方法
 * Created by davidqin on 2017/11/1.
 */
const router = require('express').Router();
const routerTable = require('./router');
const _ = require('lodash');

(function loop(map) {
  _.forEach(map, function (value, key) {
    let controller1;
    controller1 = key;
    _.forEach(value, function (value2, key2) {
      let controller2 = controller1;
      controller2 += key2;
      for (var i = 0; i < value2.length; i++) {
        let controller3 = controller2;
        let value3 = value2[i];

        let arr = value3.split('.');
        controller3 += arr[0];
        let method = arr[1];
        let path = '../controllers/' + arr[2] + '.js';
        let fuc = arr[3];

        let controllerRegistry = require(path);
        let action;
        for (let actionChild in controllerRegistry) {
          if (actionChild === fuc) {
            action = actionChild;
          }
        }
        console.log(method, controller3, action);
        router[method](controller3,controllerRegistry[action]);
      }
    });
  });
}(routerTable));

module.exports = router;

打印出来的结果有:

post /operation/post_article/categories-add addCategories
get /operation/post_article/categories-list getCategories
delete /operation/post_article/categories-delete deleteCategories
put /operation/post_article/categories-edit editCategories
post /operation/post_article/author-add addAuthor
delete /operation/post_article/author-delete deleteAuthor
put /operation/post_article/author-edit editAuthor
put /operation/post_article/author-password editAuthorPassword
get /operation/post_article/author-fetch fetchAuthor
get /operation/post_article/author-list listAuthor
get /operation/post_article/articles-list listArticles
get /operation/post_article/article-detail detailArticle
post /operation/post_article/article-add addArticle
put /operation/post_article/article-edit editArticle
delete /operation/post_article/article-delete deleteArticle
get /operation/article_comment/list listComments
post /operation/article_comment/add addComment
delete /operation/article_comment/delete deleteComment
post /v1_1/wikis/list listArticles
post /v1_1/wikis/detail detailArticle
post /v1_1/wiki-comment/add addComment
get /v1_1/wiki-comment/list listComments
post /v1_1/wiki-comment/delete deleteComment
get /v1_1/timeday/list listTimeday
post /v1_1/timeday/delete deleteTimeday
post /v1_1/timeday/add addTimeday

第三个参数是方法名。在routers文件夹同级目录下,建立controllers文件夹,创建article_controller.js(与路由表中的控制器名称保持一致)。

3. 编写controller

创建article_controller.js,在controllers目录下。

exports.addCategories = async (req, res, next) =>{
    res.send("1");
}

当有请求 post /operation/post_article/categories-add 时,会进入这个方法。你可以在多个请求URL中都指向这个方法,只要你在路由表中定义了。

4. 在 app.js 中引用

const router_map = require('./server/routes/router_map');

app.use('/',router_map);

搞定。

展开阅读全文

没有更多推荐了,返回首页