Nodejs学习笔记JavaScript学习笔记

[nodejs]为什么自己不为express写一个autoRou

2016-11-22  本文已影响611人  CharTen

根据上次的尝试,我觉得自动化的感觉还远远不够,首先是路由方面,虽然可以根据文件创建路由逻辑,但是非常重要的一点,路由的路径还是得手动填写。不仅是路由的路径,还有请求的办法,这点给人的感觉就是非常不智能了。

所以这次这个(二),就是要在原来的代码基础上做改进,要实现路由路径依据文件路径创建,请求方法根据文件名创建。而在文件里面,你只需要写两方面的内容,一个是实现路由逻辑,另一方面则是写好文档。

在这个文档方面我有三个想法,第一种想法是,在每个路由文件目录下加一个readme.md文件,然后把这个路由接口的文档写在里面,最后初始化加载路由文件的同时也读取这些readme.md的内容存储起来,然后写一个接口专门输出这些内容,再配合前端,自动构建起一个接口文档。

第二种想法是,在第一种想法的基础上,在注册路由的同时,同时也注册一个/api/doc/接口路由的接口,专门输出该路由的readme.md内容。简单讲,就是将初始化一次性读取变为分步读取吧。。。是不是有种懒加载的味道?23333.。。。

第三种想法,继承我之前的思路,直接把文档写在一个文件里面。

在这里,因为我懒(竟然这么恬不知耻的明说了?,就直接做第三种想法吧,想想每次写路由都要创建两个文件,想想都烦,而且还要用markdown写一堆相似的结构。。。这不智能对吧?渲染的工作啊,还是交给前端来,什么markdown和html都去他丫的。

好了,废话了那么多,接下来该干♂正事了。

实现


其实自动化构建文件路径路由,其实只需要一个小小的改动而已:

    var method='get';
    var route='/api/boo';
    var success=function(req,res){}
    app[method](route,success);

这里的app是express的实例,这个也是express注册路由的方法。很简单,只要把method换成遍历得到的路由文件名,比如"GET.js"的GET,然后再把它变成小写,这样就变成了:app.get(route,success)了,其余的POST|PUT|PATCH|DELET也是同理。

然后是route,这个你遍历文件夹的时候,文件路径是可得的,只要将这个文件路径拿过来,去掉有后缀名的文件名部分,就(可以吃了)可以用来当文件路径了。

不过,之前也说过,要实现RESTful式的API嘛(不懂RESTful的可以看一下阮一峰老师的介绍),有些接口需要实现后面路径自定义,比如我要根据一个id获取一篇文章的内容,首先文章的接口假如是GET /api/articles/,它的query是?aid=123456789,那么我希望能这样获取:GET /api/articles/aid/123456789或者直接GET /api/articles/123456789,但是,你用文件夹路径已经定死了,也不可能新建一个名字为*的文件夹(至少我不推荐这样做)。所以,这个是要考虑的问题。当然我相信这个小小的问题难不了大家。

我是这样做的,规定在文件名前面加个~号,比如/api/articles/~GET.js,那么该路径就会被解释为:/api/articles/*,即只要包含前面这部分的任何请求路径都由这个文件处理。这样就解决啦。什么?你想实现诸如/api/*/aid这种路由?额。。。这个。。。。等我想到方法再实现吧。。。

最后是success,这个不用说,肯定是路由文件的处理函数啦。

代码


整体代码也很简单,不过二十几行而已。。。

    var path=require('path');
    var fs=require('fs');
    var list=[];
    function readdir(dirPath, rname) {
        var arr = fs.readdirSync(dirPath);
        arr.forEach(function(item) {
            var next = path.join(dirPath, item);
            var api = rname + '/' + item;
            var stat = fs.statSync(next);
            if (stat.isDirectory()) {
                readdir(next, api);
            } else {
                if (/^[~]*(GET|POST|PUT|PATCH|DELET).js$/.test(item)) {
                    var method = item.replace(/(~|\.js)/g, '').toLowerCase();
                    var requirePath = next.replace('.js', '');
                    var route = api.replace(/\/[~]*(GET|POST|PUT|PATCH|DELET)\.js$/, '');
                    if (/~/g.test(item)) { //判断是否路由后面路径自定义
                        route += '/*';
                    }
                    var files = require(requirePath);
                    app[method](route, files.success);
                    files.info['route'] = route;
                    files.info['method'] = method;
                    files.info['index'] = list.length;
                    list.push(files.info);
                }
            }
        })
    }

很惭愧,这里做了一点点微小的工作:

这个get.js肯定是不会被读进去的,所以可以放心的当做分模块的处理文件。

啦啦,就这样~~鬼知道有没有(三).....

上一篇下一篇

猜你喜欢

热点阅读