一、Elpis
Elips-Core设计模式:
elpis-core 的架构可以看作是 Koa + 自动化加载器 (Loaders) 。
-
App 实例:作为全局上下文,保存了所有的配置、控制器、服务、中间件。
-
分层模型:
- Routing: 定义 API 路径与 Controller 方法的映射。
- Middleware: 全局或局部拦截器(如鉴权、参数校验)。
- Controller: 负责解析输入,调用 Service。
- Service: 负责数据库操作或第三方 API 调用。
- Extend : 支持通过
extend机制直接扩展app实例的功能。 - Router-Schema: 定义 API 参数校验规则(配合 AJV 使用)。
- Router : 将定义的路由注册到
koa-router中。
- 启动流程:
- 初始化 Koa 实例及环境配置。
- 依序执行 Loaders(Config -> Middleware -> Router-Schema -> Controller -> Service -> Extend -> Router)。
- 启动监听服务。
二、Loader
Config Loader ()
- 加载 config.default.js 作为基础配置
- 根据环境变量加载对应的环境配置(local/beta/procution)
- 环境配置object.assign覆盖默认配置,最终挂在到 app.config
Middleware Loader (中间件加载器)
- 扫描 app/middleware/*.js 所有中间件文件
- 支持多级目录结构
- 自动转换文件名为驼峰命名 (error-handler.js -> errorHandler)
- 挂载到 app.middlewares 使用 (app.middlewares.xxx)
Router-Schema Loader (路由校验规则加载器)
- 加载所有 JSON Schema 格式的 API 参数校验规则
- 合并所有规则到 app.routerSchema
- 配合 api-params-verify 中间件使用,基于 AJV 进行参数校验
Controller Loader (控制器加载器)
- 与 Service Loader 类似,加载并实例化所有 Controller
- 将controller定义成class,方便实例化继承,增加代码维护性
- 定义base统一处理类,处理成功和失败
- 挂载到 app.controller
- 提供render方法渲染页面实现ssr
Service Loader (业务层)
- 扫描 app/service/*.js 并实例化所有 Service 类
- 将service定义成class,方便实例化继承,增加代码维护性
- 支持多级目录结构和驼峰命名转换
- 每个 Service 自动实例化 (new ServiceModule())
- 挂载到 app.service.xxx (eg. app.service.project.getList())
Extend Loader (扩展加载器)
- 扩展 app 对象的能力
- 不支持多级目录,直接挂载到 app 上
- 例如日志能力 app.logger (app.logger.info('...'))
- 防止命名冲突 (检查 app 已有属性)
Router Loader (路由加载器)
- 创建 KoaRouter 实例
- 加载所有路由定义文件
- 提供兜底路由,临时重定向到首页
- 注册路由到 Koa 应用
框架的加载顺序经过精心设计,确保依赖关系正确:
bash
1. middlewareLoader # 加载中间件(供后续使用)
2. routerSchemaLoader # 加载路由验证规则
3. controllerLoader # 加载控制器
4. serviceLoader # 加载服务层
5. configLoader # 加载配置文件
6. extendLoader # 加载扩展功能
7. 全局中间件注册 # 注册全局中间件
8. routerLoader # 最后加载路由(依赖上述所有组件)
三、核心特性
约定优于配置
- 严格的目录结构约定
- 自动化的模块扫描和加载
- 统一的命名规范 (驼峰转换)
分层架构
- Router(定义接口执行Controller中的方法) -> Controller -> Service 清晰的调用链
- 职责分离,便于维护和测试
可扩展性
- Extend 机制可自由扩展框架能力(eg:log4js)
多环境支持
- 配置环境按环境隔离
- 日志策略按环境区分 (本地->控制台 / 生产 -> 落盘)
自动化参数校验
- 基于 JSON Schema 的声明式校验
- AJV 引擎自动校验请求参数
四、定义一个完整的 API 流程
定义 Router
javascript
module.exports = (app, router) => {
const { project: projectController } = app.controller
router.get('/api/project/list', projectController.getList.bind(projectController))
}
定义 Router-Schema
css
module.exports = {
'/api/project/list': {
get: {
query: {
type: 'object',
properties: {
proj_key: { type: 'string' },
},
required: ['proj_key']
}
}
}
}
定义 Controller
scala
module.exports = (app) => {
const BaseController = require('./base')(app)
return class ProjectController extends BaseController {
/**
* 获取项目列表
* @param {object} ctx 上下文
*/
async getList (ctx) {
const { project: projectService } = app.service
const projectList = await projectService.getList()
this.success(ctx, projectList)
}
}
}
定义 Service
javascript
module.exports = (app) => {
const BaseService = require('./base')(app);
return class projectService extends BaseService {
async getList () {
return [{
name: 'project1',
desc: ' project1 desc'
},
{
name: 'project2',
desc: ' project2 desc'
},
{
name: 'project3',
desc: ' project3 desc'
}]
}
}
}
五. 应用方法与场景
应用方法
- 定义基类 :建议通过
BaseController提供统一的success/fail返回格式。 - 利用 Service :在 Controller 中通过
app.service.xxx调用对应服务。 - 参数校验 :在
router-schema中定义 JSON Schema,配合中间件实现 API 入参自动校验。
适用场景
- 中后台管理系统:需要快速搭建标准化的 API 服务。
- 微服务节点:轻量级,启动快,易于维护。
- 模版渲染应用 :支持集成 Nunjucks 等模板引擎(例如在
app/middleware.js中配置)。