【里程碑一】:elpis-code的理解

49 阅读5分钟

一、项目目标

基于 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 原生洋葱圈模型,核心作用是实现请求参数校验、全局异常捕获、请求拦截、响应处理等通用功能,本质上是一套“请求过滤器”,统一处理所有请求的公共逻辑。

洋葱圈模型详解(重点理解):

每一个中间件对应洋葱的一层,负责处理特定的通用逻辑(如错误捕获、日志打印、参数校验等),执行遵循“先进后出”原则,具体流程如下:

  1. 请求进入后,先执行当前中间件 next() 之前的逻辑;
  2. 调用 next() 方法,进入下一个中间件,重复执行 next() 之前的逻辑;
  3. 当所有中间件 next() 之前的逻辑执行完毕后,进入洋葱圈中心,执行业务核心逻辑(如页面渲染、数据查询等);
  4. 业务逻辑执行完成后,倒序执行所有中间件 next() 之后的逻辑;
  5. 所有中间件执行完毕,将响应结果返回给客户端。

image.png

请求 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,实现路由的自动注册与管理。

核心包含三个关键功能:

  1. routes:获取所有注册的路由,当请求到达时,根据请求的路径和方法匹配对应的路由,并执行相应的路由处理函数;
  2. allowedMethods:处理 HTTP 请求中不被当前路由支持的方法(如 POST 请求发送到仅支持 GET 的路由,返回 405 Method Not Allowed 响应);
  3. prefix:抽离路由路径中的公共部分,添加统一前缀(适用于多环境部署,通过前缀区分不同环境,避免路由冲突)。

2.3 请求执行周期(必记)

理解请求从客户端到服务端,再到响应的完整流程,是掌握服务端内核的关键:

客户端发送请求 → middleware 中间件(洋葱模型进入,执行公共逻辑)→ router.routes() 获取所有注册路由 → 路由匹配(根据路径和方法匹配)→ controller 层接收请求并解析参数 → 调用 service 层处理核心业务 → service 层返回结果 → controller 层组装响应 → middleware(中间件)(洋葱模型退出,执行后续逻辑)→ 向客户端返回响应

五、最后

这套内核的核心不是“实现功能”,而是“理解架构”——通过手动搭建内核,深入理解服务端的运行机制,打破前端开发者对“底层架构”的陌生感,也谢谢哲哥的课程让我去很清晰的了解这些东西!!