一、项目目标
基于 Koa.js 构建轻量化 BFF 服务端内核引擎,实现自动化 Loader 机制、高可扩展插件化架构,原生支持洋葱模型中间件组合与服务端渲染(SSR) 能力,完成从业务页面开发到底层框架设计的技术跃迁。
通过自研内核架构,实现从接口开发向内核架构设计的能力升级,深度掌握服务端请求全生命周期、执行时序、模块分层依赖与架构解耦思想,打造高可用、易维护、可快速迭代的企业级 BFF(是位于前端与后端微服务之间的专属适配层,核心价值是为前端 “量身定制接口”,但会增加架构复杂度与运维成本。) 底层支撑体系
二、架构设计
1、核心分层结构 先上分层目录结构,直观理解各模块的组织关系:
elpis-core
|
| -- loader
|
| -- middleware 中间件
| -- router-schema 路由声明
| -- controller 请求控制层
| -- service 业务逻辑层
| -- config 配置层
| -- extend 扩展层
| -- router 路由注册
|
| -- index.js
2、各层定位与详解
每一层都有明确的职责,互不越界,共同构成完整的服务端内核。
1. middleware(中间件层)
采用 Koa.js 原生洋葱圈模型,核心作用是实现请求参数校验、全局异常捕获、请求拦截、响应处理等通用功能,本质上是一套“请求过滤器”,统一处理所有请求的公共逻辑。
洋葱圈模型详解(重点理解):
每一个中间件对应洋葱的一层,负责处理特定的通用逻辑(如错误捕获、日志打印、参数校验等),执行遵循“先进后出”原则,具体流程如下:
- 请求进入后,先执行当前中间件 next() 之前的逻辑;
- 调用 next() 方法,进入下一个中间件,重复执行 next() 之前的逻辑;
- 当所有中间件 next() 之前的逻辑执行完毕后,进入洋葱圈中心,执行业务核心逻辑(如页面渲染、数据查询等);
- 业务逻辑执行完成后,倒序执行所有中间件 next() 之后的逻辑;
- 所有中间件执行完毕,将响应结果返回给客户端。
请求 ctx → middleware1(next前)→ middleware2(next前)→ middleware3(next前)→ 核心业务逻辑 → middleware3(next后)→ middleware2(next后)→ middleware1(next后)→ 响应 ctx
2. router-schema(路由声明层)
将路由信息抽象为结构化声明,统一定义路由路径、请求方法(GET/POST等)、接口参数校验规则,实现路由配置的规范化、标准化,便于维护和扩展。
示例代码(可直接复用):
"/api/query/article/list": {
get: {
headers: {},
query: {
type: "object",
properties: {
page: {
type: "number",
minimum: 1
},
size: {
type: "number",
minimum: 1,
maximum: 100
}
},
required: ["page", "size"]
},
body: {},
params: {},
controller: "article.getList" // 绑定对应的控制器方法
},
}
3. controller(请求控制层)
作为 HTTP 请求与业务逻辑的桥梁,核心职责是:
- 接收客户端发送的 HTTP 请求,解析请求参数;
- 调用对应的 service 层方法处理数据;
- 组装响应结果并返回给客户端。
✅ 核心原则:不编写复杂业务逻辑,仅负责“请求接收-响应返回”,实现请求与业务的解耦。
4. service(业务逻辑层)
被 controller 层调用,是核心业务逻辑的承载层,主要负责:
- 处理具体的业务逻辑(如数据过滤、业务规则判断);
- 数据查询、数据处理(后续可直接调用 SQL 语句或 ORM 工具);
- 第三方接口调用(如调用支付接口、短信接口);
- 处理完成后将结果返回给 controller 层。
5. config(配置层)
负责管理项目不同环境的配置信息,采用“默认配置+环境覆盖”的模式,实现环境配置的隔离与统一管理。
管理的配置包括:
- 环境名称(开发环境、测试环境、生产环境);
- 接口超时时间、数据库配置、密钥信息;
- 路由前缀、日志配置等随环境变化的数据。
核心逻辑:基础配置放入 default 文件,挂载时根据当前环境,自动覆盖对应配置并加载。
6. extend(扩展层)
用于扩展框架能力,允许开发者将自定义工具函数、日志打印模块、全局方法等引入到 app 实例上,供整个内核引擎全局调用。
常见扩展场景:
- 扩展日志工具,实现请求日志、错误日志的统一打印;
- 扩展工具函数,封装常用的字符串处理、时间格式化等方法;
- 扩展全局常量、通用枚举等。
7. router(路由注册层)
根据 router-schema 中定义的结构化路由信息,动态生成路由并挂载到 Koa 实例上,同时绑定对应的 controller 和 middleware,实现路由的自动注册与管理。
核心包含三个关键功能:
- routes:获取所有注册的路由,当请求到达时,根据请求的路径和方法匹配对应的路由,并执行相应的路由处理函数;
- allowedMethods:处理 HTTP 请求中不被当前路由支持的方法(如 POST 请求发送到仅支持 GET 的路由,返回 405 Method Not Allowed 响应);
- prefix:抽离路由路径中的公共部分,添加统一前缀(适用于多环境部署,通过前缀区分不同环境,避免路由冲突)。
2.3 请求执行周期(必记)
理解请求从客户端到服务端,再到响应的完整流程,是掌握服务端内核的关键:
客户端发送请求 → middleware 中间件(洋葱模型进入,执行公共逻辑)→ router.routes() 获取所有注册路由 → 路由匹配(根据路径和方法匹配)→ controller 层接收请求并解析参数 → 调用 service 层处理核心业务 → service 层返回结果 → controller 层组装响应 → middleware(中间件)(洋葱模型退出,执行后续逻辑)→ 向客户端返回响应
五、最后
这套内核的核心不是“实现功能”,而是“理解架构”——通过手动搭建内核,深入理解服务端的运行机制,打破前端开发者对“底层架构”的陌生感,也谢谢哲哥的课程让我去很清晰的了解这些东西!!