:::info ℹ️ 这篇文集主要期望通过对 Node.js HTTP Server => Koa.js => Egg.js => Midway.js 的封装和演进过程,去对服务端框架设计做一些分析和思考,愿有所收获和启迪 🙏🏻 :::

概述

按照封装的层级结构,几个要素对应着如下的关系:
主流 Node.js 服务端应用框架实现分析 & 思考 - 图1

  • Node.js Core API 提供了上层所需要的底层 API 调用,包括:net child_process 等基础模块
  • Koa 实现了对 HttpRequest / HttpResponse 的基于洋葱模型的封装,作为核心请求响应处理操作的范式实现,提供 middleware 的插拔机制
  • Egg 则从「企业级 Node.js」服务入手,做了更多通用能力层的实现,包括插件系统(扩展系统)、服务进程线程调度,微服务的管理,约定的应用级配置(路由、生产环境),编程实现风格等等
  • Midway 则是具体的业务和组织相关的封装和实现,比如 Alibaba 集团的服务,一些约定俗成的写法,比如服务注入,启动巡检等等,是典型的「业务型框架」

所以接下来,我们便从底层开始,由最底层的设计向上 🔼 演进,探一探每一层框架的关注点和其中源代码层的实现思考,做一次充分的剖析和学习。

Here we go ~

Node.js 相关 API 设计

温习一下 Node.js 主要使用到的 Core API:node.js
这是操作系统能力的封装,也是 Node 对服务器端编程的基础 API。

Koa 设计分析

参考早期对 Koa 的分析 & 思考:Express / Koa

Koa 提供了经典的处理 Web 请求的 洋葱模型,用最少的代码实现了最重要的核心,简洁、优雅,富有启发性,不愧是大佬,亲手设计的 express 和 koa 是一种思想,一种模式,一种术。

Egg 设计分析

Egg 框架指南:官方文档
Egg 框架设计和实现的个人探索摘要:Egg 设计分析和思考

Egg 的产生,我理解是严格基于了 Koa 的思想,在上层封装了 Node.js 做企业级服务端开发的细分问题域,提供了基础抽象。比如:服务(Service)、控制器(Controller)、多进程管理(Process)、框架插件(Plugin)、框架扩展(FrameworkExtension)等等,提供一个企业级的核心,是对 Koa 思想的延展。

Midway 设计分析

Middleway 官方文档:介绍
Middleway 个人思考:Midway 框架分析和思考

总体来说,Midway 不是 Egg,也不是 Koa,我感觉更像是一个淘系业务驱动的庞然大物,它想要兼容一切,也想要包含主流的服务端框架技术,想要用自己 IoC 系统等思想去整合别的技术栈,让多种框架杂糅在一起,形成一个无所不能的业务型框架。

我感觉 Midway 的诞生,估计是在业务及其复杂的背景下产生的,里面看到的是比较多的妥协和无奈 🤷🏻‍♀️,想要独树一帜,却又受限于存量的业务模块的兼容;要追求技术的优雅和精致,却无奈于业务时间的剥离 … 这是一种矛盾的设计体。不过也为这样的框架体系支撑了集团诸多业务而感到欣慰吧。

WIP:Next

后续关注一下业界开源框架的设计,看能力几何?

小结

Node.js 服务端框架确实各有千秋,层层封装也是颇有意思。但是我一直觉得框架的使用一定要对症下药,根据想要解决的问题规模来判定框架的设计,这也是规避银弹的设计的方式。我越发的理解在设计框架的时候「洁癖」的重要性。Koa => Egg => Midway,阅读不同框架的实现会发现,越接近业务层,会发现代码会越来越不那么「洁癖」了。也算最终给自己一些启发:无论处于哪一层,代码的洁癖和精细化设计的保持一定是长久治理之道,对于破坏这些设计的实现,绝不姑息。