看到有些程序员不理解,为什么一个网站只有一个接口。什么叫网站只有一个接口?这么说吧,网站路由大家都知道吧,上面的意思就是整个网站就一个路由!这很夸张吗?其实,这在MVC模式下开发是很常见的一种网站接口的设计方式。有人就问了,这么做难道不会导致性能问题吗?如果是分布式开发,这种接口咋办?

打开网易新闻 查看更多图片

一般来说,我们在设计网站后台接口的时候,通常都是一个接口一个路由,比如说在传统静态路由也就是纯HTML时代,几乎每个页面的地址就是一个路由。

比如说http://www.xxxxxx.com/index.html,这里所描述的就是index页面所在的完整路由。如果index这个页面存在于某个文件夹内,那么index页面所在路由就可以这么描述:http://www.xxxxxx.com/文件夹名称/index.html。

在MVC这种网站开发模式出现伊始,因为视图(View)和控制器(Control)是耦合在一块的,类似于Jsp和Asp这种开发模式,因此很多公司在开发网站时还没脱离页面和路由强关联的这个思想。包括Java最开始的HHS框架(如果我没记错的话)和.Net的.Net MVC,此时的MVC架构还没真正做到前后端分离。

但是,当MVC这种网站开发思想越来越深入人心后,MVC架构转变成了真正的前后端分离,即前端是一套开发框架,后端又是一套开发框架。

比如现在大部分公司前后端框架基本都是Vue+Spring MVC或者是Vue+.Net Core MVC这种组合。

当后端完全放弃了控制前端路由之后,后端也开始放飞自我了,也就是大家所看到的,有很多网站的接口路由只指向一个地址!

会影响接口访问速度吗?

我不认为这种设计会影响网站的访问速度!

简单说下我的理解,不管是Spring MVC还是.Net/.Net Core MVC其实访问接口的时候都会先经过一个入口,我们通常叫作调度入口,由调度入口对请求信息进行分析后,最终反射到具体路由上去。

也就是说,抛开一个网站只有一个路由不谈,即使是一个接口一个路由,其实所有接口请求都需要经过一个入口。所以,网站只设一个路由,又有什么问题呢?

接口反射

那么,当一个网站只有一个路由地址,我们怎么去访问各个接口呢?

很简单,只需要带一个参数,告知需要访问的具体接口地址就行了。

比如说我们可以把上面的例子改一改,改成http://www.xxxxxx.com/home/rest?method=index!

这个应该都能看懂吧,home代表控制器,rest代表这个控制器的的唯一接口,而“?”后面的method则是参数,参数值是index。

具体到了rest这个接口里怎么做呢?首先,我们的控制器方法里面应该有一个叫作“index”的方法。

当我们在接收method的值的时候,我们可以通过反射的方式去获取这个叫作index的方法,这样我们就可以得到并且执行这个方法,且将这个方法的结果返回给rest接口并返回给外部。

打开网易新闻 查看更多图片

整个接口的访问到这里就完成了,如果index这个函数也有入参,我们也可以直接将“?”后面的所有参数再反射到index函数里面,再去调用。

说到这里,有些人可能会疑惑,为什么要这么干?

统一鉴权,模块化开发

其实,这么干的主要原因还是插件式开发变得更加容易了,因为即使是普通方法也可以通过反射调用出来,比如.Net就可以通过动态加载dll并且反射里面的方法,要知道,单纯的MVC,只有在控制器里面的方法才能被路由找到!

而所有接口的入口都指向一个的话,我们就可以在这个入口里面做很多东西。

比如说对所有接口进行统一的接口鉴权、参数验签、参数验证、IP过滤等等!

这时候有人会顾虑效率问题,其实,如果接口设计的足够好,效率大体上和一个接口一个路由大差不差!

但是,当一个网站的接口数量达到一定量级,再好的设计也顶不住不是吗?

这时候,我们可以采取模块化路由的方式。

比如说假设我们现在网站分商品模块、订单模块、用户模块的时候,我们完全可以将这些模块分出来,那么对应的路由就可以设计成shop/rest、order/rest、user/rest......

也可以将接口鉴权单独做成一个WebApi,由这个WebApi转发到其他Api。

你们如果有空的话,去一些大型网站逛逛,看看他们的路由地址是不是也是这么设计的?

这样,既可以解决分布式问题又可以解决网站接口请求效率的问题。

结语

总之,一个网站只有一个路由,或者按照大类分路由这个设计模式存在即有它的道理,虽然说,这种设计模式您可能没见过觉得不可理解,但是既然有人这么用了,自然有它的道理,并且这么用的人还不少呢!

我过去任职的一些公司也使用过这种方法,目前来说没看到过有任何问题。