038-API层架构设计

📅 2026/7/19 22:48:23
038-API层架构设计
038 — API 层架构设计从枚举定义到模块化 API 管理简介随着业务复杂度的增长网络请求的管理方式直接影响项目的可维护性。MoneyTrack 采用了一套分层清晰的 API 架构底层是单例 Axios 客户端037 篇已述中间层是枚举驱动的接口地址集中管理上层是按业务域划分的模块化 API 文件。这套架构使得 30 个网络端点的查找、维护和调试变得井然有序新增一个接口只需添加枚举值和对应方法无需改动既有代码。API 三层架构全景 HTTP 客户端 枚举层 (单一数据源) API 模块层 ViewModel 调用层HomeViewModel.etsBillViewModel.etsUserViewModel.etsBill.etsgetBillList()Asset.etsgetAssetList()User.etslogin / logout / updateUserInfoRequestUrlMap30 端点枚举Request.etsAxios 单例 拦截器核心知识点1. API 枚举集中管理将所有后端接口地址定义在统一的RequestUrlMap枚举中实现接口地址的单一数据源避免硬编码字符串散落在各文件中容易拼写错误枚举统一管控。自文档化枚举名即接口用途说明一目了然。类型安全配合 TypeScript 类型检查修改地址时全局可控。以下是 MoneyTrack 项目中RequestUrlMap枚举的完整展示覆盖用户、家庭、账本、账单、资产五大模块exportenumRequestUrlMap{/** 用户相关 */USER_LOGINuser/login,USER_LOGOUTuser/logout,USER_INFOuser/info,USER_MEMBERSHIPuser/membership,/** 家庭相关 */FAMILY_CREATEfamily/create,FAMILY_JOINfamily/join,FAMILY_MEMBERSfamily/members,FAMILY_LEAVEfamily/leave,FAMILY_REMOVE_MEMBERfamily/removeMember,/** 账本相关 */ACCOUNT_BOOK_LISTaccountBook/list,ACCOUNT_BOOK_CREATEaccountBook/create,ACCOUNT_BOOK_UPDATEaccountBook/update,ACCOUNT_BOOK_DELETEaccountBook/delete,ACCOUNT_BOOK_SWITCHaccountBook/switch,/** 账单相关 */BILL_LISTbill/list,/** 资产相关 */ASSET_LISTasset/list,}2. 模块化 API 文件按业务领域将 API 调用拆分到独立文件每个文件只负责一个业务模块。采用类 单例导出模式既保持了面向对象的封装性又方便上层调用// Asset.ets — 资产模块 APIclassAssetApis{publicgetAssetList(ownerId?:number):PromiseBaseResponse{constparams:Recordstring,Object{};if(ownerId!undefined){params[ownerId]ownerId;}returnrequest.get(RequestUrlMap.ASSET_LIST,{params});}}constinstancenewAssetApis();export{instanceasAssetApis};// User.ets — 用户模块 APIclassUserApis{publiclogin(params?:UserLoginReq):PromiseBaseResponse{returnrequest.get(RequestUrlMap.USER_LOGIN,{params});}publiclogout():PromiseBaseResponse{returnrequest.get(RequestUrlMap.USER_LOGOUT);}publicupdateUserInfo(data:UpdateUserInfoReq):PromiseBaseResponse{returnrequest.put(RequestUrlMap.USER_INFO,data);}publicsubscribeMembership():PromiseBaseResponse{returnrequest.post(RequestUrlMap.USER_MEMBERSHIP);}publicgetMembershipInfo():PromiseMembershipInfoResp{returnrequest.get(RequestUrlMap.USER_MEMBERSHIP);}}constinstancenewUserApis();export{instanceasUserApis};3. 类型安全的泛型约束每个 API 都明确定义了请求参数类型和响应数据类型利用 TypeScript 泛型在编译期捕获类型错误// 定义泛型响应结构exportinterfaceBaseResponseTany{code:number;message:string;data:T;}// 在 API 方法中使用泛型约束classBillApis{publicgetBillList(memberId?:number):PromiseBaseResponseBillItem[]{constparams:Recordstring,Object{};if(memberId!undefined){params[memberId]memberId;}returnrequest.get(RequestUrlMap.BILL_LIST,{params});}}当后端返回的数据结构发生变化时只需修改泛型类型定义所有调用方都会收到编译警告极大降低回归风险。4. API 版本管理URL 中携带版本号是管理 API 演进的通行做法。在request层通过 baseURL 携带主版本号或通过拦截器自动注入版本参数// 方案一baseURL 携带版本号constinstanceaxios.create({baseURL:https://api.moneytrack.com/v2/,// 整个应用使用 v2 版本});// 方案二按模块在 API 路径中指定版本enumRequestUrlMap{USER_LOGIN_V1v1/user/login,USER_LOGIN_V2v2/user/login,// 渐进式升级}特性枚举集中管理硬编码字符串可维护性一处修改全局生效四处查找替换自文档化枚举名说明用途需额外注释类型检查编译期检测运行时才能发现协作效率新人快速了解接口需翻阅文档最佳实践枚举命名规范采用模块_动作格式如USER_LOGIN、BILL_LIST按模块分组并用注释分隔方便快速定位。API 文件粒度一个业务模块一个文件文件内只导出类实例单例避免命名空间污染。类型优先先定义请求/响应的 TypeScript 接口再实现 API 方法。让类型定义驱动开发流程。渐进式版本升级新旧版本接口枚举共存逐个模块迁移避免大版本一次性升级的风险。推荐参考文档TypeScript 枚举与泛型文档RESTful API 版本管理最佳实践