之前的设想
「理想总是高于现实」,这tmd大概说的就是我们现在cloudwood的代码。
在规划目录结构和业务流之前,我是这么想的,大概用下图可以表示:

有两点需要说明下:
-
为啥要用多Express实例来区分PC/Mobile(NA)/H5,而不是纯靠路由区分,原因在于:
-
错误隔离、因为不同的Express可以控制在实例内部报错,业务之间不会相互影响;
-
配置隔离,因为不同的Express可以使用自己的配置,比如模板类型、静态资源目录等。
-
-
为啥API要单独设计?因为我们API除了对外提供服务,还要为内部其他子系统(Express)提供数据相关的工具方法。
当然,这一切的前提是我们使用了一套BaaS服务,为了方便,我们没有在物理层面进行服务拆分,只是在代码模块层面做了拆分。
但是,即便是这样,模块也没分好。。。
-
本来设计的是util模块(一个独立模块)里放纯粹的工具方法(比如JSON处理、时间处理)等,但是现在里面却塞了大量的跟业务耦合的代码;
-
API被纯粹当成了Restful HTTP 接口,完全没体现出来内外分离的感觉;
-
Express实例之间尽然出现相互引用;
-
作为最外层挂载器的Base Express,原本设计的意义在于处理全局错误和全局(400、500)handler,结果却变成了业务池,注入了大量代理代码(代理到HTTP)。
所以,现在的cloudwood惨不忍睹。
我们该怎么办
微服务改造 + subtree。
说白了就是要把之前耦合在一起的代码拆成独立的服务,把之前共有依赖的本地调用拆分为subtree模块:

那么,什么情况下拆分成独立的服务,什么情况下拆分为独立的供他人嵌入的subtree模块。判断方法很简单:
如果这个模块纯粹依赖特定输入提供特殊输出,需要以HTTP的方式对外提供服务,那么就拆分为服务;如果这个模块只是提供通用处理的方法,不需要和业务数据打交道,那么就拆分为subtree。
这样看来,之前的Internal API、util比较适合于拆分为subtree模块,Express实例可以拆分为服务。
当然,服务是可以嵌套的,我们做的第一步是要先拆除去,然后再说……