web学习:服务端开发的业务需求-路由解析

后端(服务端)对于前端(客户端)的来说就像是中转站,后端调用底层(操作系统)服务上层(浏览器),而他们之间的桥梁便是IO流,后端与操作系统之间的是文件IO流,与前端的便是网络IO流。这次,我们先探讨下服务端与浏览器间的业务需求。

路由解析:

经过层层网络协议的解析,我们最终从浏览器请求中获取到了相关数据。但如何处理这些数据呢,这就需要我们去解析请求的URL,并且分发相对应的处理逻辑。而URL的解析映射又分了多种方式。下面简单介绍下。

  • 文件路径型:

这种解析方式就是URL路径与网站的目录的路径一致,处理起来十分简单,当我们的请求是获取一个文件,如html页面时,简单示意,如下:

const path=require('path');
const url=require('url');
const fs=require('fs');复制代码
function getFile(req,res,root) {
    //获取url路径
    var pathname=url.parse(req.url).pathname;
    fs.readFile(path.join(root,pathname),function (err,file) {
        res.end(file);
    })
}复制代码

当我们需要根据URL做不同业务逻辑处理时,也是寻找对应的文件 ,如idnex.php,然后把它交给对应的脚本解析器,并传入HTTP上下文即可。记得很早之前学习PHP时,使用的Apache服务器就是文件路径型的URL处理方式。

但使用nodeJs时,由于前后端文件后缀都是.js,这样就很难判断哪个文件是nodeJs的脚本,哪个是前端脚本,所以,得用另一种解析方式。

  • 手动映射型:

URL路径和文件路径是没有任何关系的,所以我们可以手动映射URL到对应的业务逻辑上,不用像文件路径一样,每个url都得对应一个文件,分发处理方面更加灵活方便。简单示例:

//业务逻辑
function todo(req,res) {
    //TODO
}
//业务逻辑的集合
var routes=[];
//url映射
function use(path,action) {
    routes.push([path,action]);
}
//http请求响应入口程序。
function httpServer(req,res) {
    var pathname=url.parse(req.url).pathname;
    //分发业务
    for(var i=0;i<routes.length;i++){
        var route=routes[i];
        if(pathname===route[0]){
            var action=route[1];
            action(req,res);
            return;
        }
    }
}
//映射一个url
use('/user/todo',todo);复制代码

是不是很简单,但我们还忽略了一点,那就是url参数,不同框架的标识不同,nodeJs的表示法是/todo/:params,就是冒号后面的那个值表示url传递的参数,所以我们使用手动映射时,就不能直接匹配字符串了,得用正则表达式去解析url的参数出来,至于怎么弄,好像真的有点复杂,具体就不演示了,大概知道就行。当然,还有url的查询字符串,就是?a=1&b=2这些,node的api有提供如何去获取,这里也不演示了。

手动映射的确很灵活,但项目过大的话,映射的路由也会变多过难以维护。而且查询需要费时间,当然用map的话,时间可以缩短。所以还有另一种映射方式,无需去维护路由的映射。

  • 自动映射型:

就是事先约定好某个文件中下保存了某个路由的业务逻辑,如:url路是/controls/action/123,我们就约定好controls文件对应路径/controls,并且用controls文件下action函数处理/controls/action,路径剩下的便是该url的参数。简单示例:

function httpServer(req,res) {
    var pathname=url.parse(req.url).pathname;
    var path=pathname.split('/');
    var controller=path[1];
    var action=path[2];
    var args=path.slice(3);
    var module=require(controller);
    module[action].apply(null,[req,res].concat(args));
}复制代码

是不是和文件路径映射有点像,其实原理都一样的,具体细节上的不同这里就不讲了。接下来讲下reslt。

  • reslt规范:

先说下它的全称啊,Representational State Transfer(表现层状态转移),这句话具体什么意思呢,我也不是很清楚哈,大概说下我从多篇文章中以及项目使用中获得的理解吧。

reslt它是一种规范,什么规范呢,就是将http的请求方法也加入路由的过程中。如我们是通过url的路径来映射业务逻辑的,但如果遵循reslt规范,那就是判断http的请求方法后,再结合url的路径来映射对应的业务逻辑。而这就体现了reslt的设计思想,那就是通过url来设计资源,通过请求方法来定义资源的操作,通过accept请求字段来决定资源的表现形式。

嗯,希望我的理解是正确的,一段简单的示例代码:

var app={};
var routes={};
['get','put','delete','post'].forEach(function (md) {
    routes[md]={};
    app[md]=function (path,action) {
        routes[md].push([path,action]);
    }
});

function httpServer(req,res) {
    var pathname=url.parse(req.url).pathname;
    var method=req.method.toLowerCase();
    if(routes[method]){
        for(var i=0;i<routes[method].length;i++){
            var route=routes[i];
            if(pathname===route[0]){
                var action=route[1];
                action(req,res);
                return;
            }
        }
    }
}
app.get('/todo',function () {});
app.post('/todo',function () {});
app.delete('/todo',function () {});
app.put('/todo',function () {});复制代码

先写到这儿,好累啊,本来想一次全写完服务端的业务需求的,分批次来吧。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值