一套轻量 Node 框架的架构理解与工程感悟(里程碑1)

11 阅读3分钟

一套轻量 Node 框架的架构理解与工程感悟

最近完成了里程碑 1,这是我对这块elpis-core的简单理解。在这个阶段里,我不仅学会了如何编写 Elpis 这个项目,更重要的是形成了更系统的架构思维和编码习惯。
从展示层、BFF 层到数据层,每一层的设计都让我对“工程化开发”有了更深刻的理解。


里程碑 1:完成 elpis-core(BFF 底层设计)

elpis-core 的整体设计可以概括为三层:

  • 接入层:router 路由分发、规则校验、路由中间件
  • 业务层:controller 处理器、env 环境分发、config 配置、extend 拓展、定时任务
  • 服务层:service 处理器(业务能力与数据访问)

这种分层的价值是职责清晰:
接入层负责“请求进来怎么走”,业务层负责“逻辑怎么组织”,服务层负责“能力怎么沉淀”。


核心启动流程(主线)

核心流程如下:

  1. 初始化 Koa 实例
  2. 按顺序加载多个 Loader
  3. 加载 app/middleware.js,注册全局中间件
  4. 加载路由并挂载到 app
  5. 启动 8080 端口

这个流程体现了一个关键思想:先装配能力,再执行能力。


多个 Loader 的职责

1) middlewareLoader

扫描 app/middleware,把每个中间件模块装配到 app.middlewares.xxx。
价值在于把“定义中间件”和“使用中间件”解耦;app/middleware.js 只负责引用和排序,不需要关心文件细节。

2) routerSchemaLoader

扫描 app/router-schema,合并为 app.routerSchema。
这样参数校验(Ajv)就可以独立于路由和控制器,形成“声明式接口约束”。

3) controllerLoader

扫描 app/controller,实例化控制器并挂到 app.controller.xxx。
路由层只负责绑定,不夹杂业务实现,职责更清晰。

4) serviceLoader

扫描 app/service,实例化服务并挂到 app.service.xxx。
控制器调用服务,服务聚焦业务逻辑和数据访问,符合常见后端分层习惯。

5) configLoader

读取 config.default.js 与环境配置(local/beta/prod),合并到 app.config。
它建立了“同一套代码,多环境运行”的能力基础。

6) extendLoader

扫描 app/extend,向 app注入扩展能力(如 logger)。
本质是应用实例的插件化增强,便于横向扩展。

7) routerLoader

扫描 app/router,将路由统一注册到一个 koa-router 实例并挂载到 Koa。
这是“把所有准备好的对象接上线”的最后一步。


相关 Koa 插件的理解

koa-nunjucks-2

koa-nunjucks-2 是 Koa 的模板渲染中间件,把 Nunjucks 集成到 Koa 中,用于服务器端渲染 HTML(SSR 场景)。

koa-bodyparser

koa-bodyparser 用于解析 HTTP 请求体,并将数据挂载到 ctx.request.body
如果不使用它,Koa 默认无法直接获取请求体中的 body 数据。

ajv(接口规则校验)

使用 Ajv 定义接口 schema 规则,可以让 API 输入格式更规范、更可读,也能在接入层提前拦截非法请求。

签名校验

前端与服务端约定签名规则和过期时间,通过签名 + 时效校验提升接口安全性,属于基础但重要的安全设计思路。


感悟

完成里程碑 1 后,我最大的收获不是“会写某个接口”,而是逐渐形成了以下工程习惯:

  • 先做分层与边界,再写具体逻辑
  • 代码注释,有些注释就有种优雅的感觉,学会养成核心逻辑写注释习惯。
  • 先约束输入(校验、签名),再执行业务

对我来说吧,Elpis 不只是一个项目,更是一次从“功能开发思维”走向“架构工程思维”的实践。