News
首页  -  资讯  - 
TypeScript封装通用RESTful BaseAPI,后台接口代码精简80%
TypeScript封装通用RESTful BaseAPI,后台接口代码精简80% 本文适用场景 :Vue3+TS+Axios 中后台管理系统、遵循RESTful接口规范方案、大量同质化增删改查业务 阅读收益 :一套可直接落地的通用CRUD封装、区分简易/复杂分页查询最佳实践、对接自定义表格Hook完整用法、RPC旧式接口迁移方案 前置依赖 :项目已封装全局axios请求实例 @/utils/ht...

TypeScript封装通用RESTful BaseAPI,后台接口代码精简80% 本文适用场景 :Vue3+TS+Axios 中后台管理系统、遵循RESTful接口规范方案、大量同质化增删改查业务 阅读收益 :一套可直接落地的通用CRUD封装、区分简易/复杂分页查询最佳实践、对接自定义表格Hook完整用法、RPC旧式接口迁移方案 前置依赖 :项目已封装全局axios请求实例 @/utils/http 一、项目痛点 开发中后台系统,绝大多数业务模块(客户、角色、菜单、商品、部门)接口高度同质化:分页列表、详情、新增、编辑、单删、批量删除。 传统写法存在大量问题: 每个业务模块重复手写7个基础请求方法,代码冗余、维护成本高 旧式RPC接口命名杂乱: queryPage、save、update、batchDelete ,接口风格不统一 多条件筛选、日期区间、多选数组参数,GET请求超长导致接口报错 分页参数、返回体类型重复定义,TS类型复用性极差 基于以上问题,本文封装一套 符合机构级RESTful规范 的通用 createBaseAPI ,一行代码生成全套CRUD接口,开箱即用。 二、统一RESTful接口约定 适配说明 :本文约定为适配中后台最优方案,可根据后端接口规范,自行修改请求路径、请求方式、批量删除入参格式 以资源 users 为例,基础路径 baseUrl: /api/users ,全套接口规范如下: 请求方法 接口路径 业务说明 适用场景 GET /api/users 简易分页列表 筛选条件少、无数组/日期范围,参数拼URL POST /api/users/search 复杂分页查询 多选、日期区间、多表单筛选,参数放Body,规避URL超长 GET /api/users/:id 获取单条详情 表单回显、弹窗详情 POST /api/users 新增资源 新增业务信息 PUT /api/users/:id 全量编辑资源 覆盖式修改数据 DELETE /api/users/:id 单条删除 单行删除操作 DELETE /api/users 批量删除 入参 {ids: string[]} ,表格多选删除 核心选型技巧 简单筛选:优先GET list,写法简洁、缓存友好 复杂筛选:必用POST search,避免浏览器URL长度限制、特殊参数转义问题 后端批量路径自定义:可手动扩展方法适配 /batch-delete 这类非标接口 三、核心利器类 createBaseAPI 源码 新建文件 @/utils/createBaseAPI.ts ,完整类型封装,兼容泛型约束,完美适配TS类型提示 import { http } from '@/utils/http' /** 后端统一分页返回结构体 */ export interface PageResult { list : T[] total : number } /** 通用分页入参 */ export interface PageParams { page : number size : number } /** 业务自定义参数映射:列表筛选/新增/编辑类型约束 */ interface QueryMap { /** 列表查询筛选参数 */ list?: Record < string , any > /** 新增请求体 */ create?: Record < string , any > /** 更新请求体 */ update?: Record < string , any > } /** * 生成RESTful通用CRUD API * @param baseUrl 资源基础接口地址 * @returns 内置全套增删改查方法 */ export function createBaseAPI( params : { baseUrl : string }) { const { baseUrl } = params return { /** GET /resource/:id 获取详情 */ getById ( id: string ) { return http. get ( ` ${baseUrl} / ${id} ` ) }, /** GET /resource 简易分页列表 */ list ( params: PageParams & Q[ 'list' ] ) { return http. get < PageResult >(baseUrl, params) }, /** POST /resource/search 复杂分页筛选 */ search ( params: PageParams & Q[ 'list' ] ) { return http. post < PageResult >( ` ${baseUrl} /search` , params) }, /** POST /resource 新增资源 */ create ( data: Q[ 'create' ] ) { return http. post (baseUrl, data) }, /** PUT /resource/:id 全量更新资源 */ update ( id: string , data: Q[ 'update' ] ) { return http. put ( ` ${baseUrl} / ${id} ` , data) }, /** DELETE /resource/:id 单条删除 */ remove ( id: string ) { return http. delete < void >( ` ${baseUrl} / ${id} ` ) }, /** DELETE /resource 批量删除 */ removeBatch ( ids: string [] ) { return http. delete < void >(baseUrl, { data : { ids } }) } } } 四、业务模块快速定义API 以用户模块为例,新建 @/apis/user.ts ,仅需定义实体类型+自定义筛选类型,一行生成全部CRUD,非标接口单独拓展即可。 import { createBaseAPI } from '@/utils/createBaseAPI' import type { PageResult } from '@/utils/createBaseAPI' /** 用户实体类型 */ export interface UserItem { id : string name : string age : number phone : string address : string status : number } /** 用户角色附属类型(拓展非标接口) */ export interface UserRoleItem { id : string roleName : string } /** 自定义用户模块:列表筛选、新增、编辑入参类型 */ interface UserQuery { list?: { name?: string status?: number // 多选状态筛选 statusList?: number [] // 日期区间筛选 dateRange?: string [] } // 新增字段约束 create?: Partial < UserItem > // 编辑字段约束 update?: Partial < UserItem > } /** 自动生成用户全套CRUD接口 */ export const userAPI = createBaseAPI< UserItem , UserQuery >({ baseUrl : '/api/users' }) /** ========== 非标REST接口单独拓展 ========== */ /** 获取用户绑定角色 */ export function getUserRoleList ( id: string ) { return http. get < UserRoleItem []>( `/api/users/ ${id} /roles` ) } 五、页面直接调用使用 组合式API页面直接调用,TS自动推导入参出参,自带代码提示,无需重复写url和method import { userAPI } from '@/apis/user' // 1. 获取详情 const detail = await userAPI. getById ( '1' ) // 2. 简易分页查询(少量筛选条件) const pageData = await userAPI. list ({ page: 1 , size: 10 , name: '' , status: 1 }) // 3. 复杂条件查询(多选、日期范围) const searchData = await userAPI. search ({ page : 1 , size : 10 , name : '' , statusList : [ 1 , 2 ], dateRange : [ '2024-01-01' , '2024-12-31' ] }) // 4. 新增用户 await userAPI. create ({ name : '张三' , age : 18 , status : 1 }) // 5. 编辑用户 await userAPI. update ( '1' , { name : '李四' }) // 6. 单条删除 await userAPI. remove ( '1' ) // 7. 批量删除 await userAPI. removeBatch ([ '1' , '2' , '3' ]) 六、适配项目通用表格Hook useTable 中后台必备表格Hook联动,自动判断筛选条件,动态切换 GET/list / POST/search,增强请求体验,适配Element Plus/Ant Design Vue表格。 import { userAPI } from '@/apis/user' import { useTable } from '@/hooks/useTable' import { computed, reactive } from 'vue' // 表格筛选条件 const queryParams = reactive ({ name : '' , status : undefined as number | undefined , statusList : [] as number [], dateRange : [] as string [] }) // 判定:存在数组/日期条件,自动走POST复杂查询 const useSearchAPI = computed ( () => queryParams. statusList . length > 0 || queryParams. dateRange . length > 0 ) // 表格全局状态、请求、分页封装 const { tableData, pagination, search, loading } = useTable ({ listAPI : ( pageInfo ) => useSearchAPI. value ? userAPI. search ({ ...pageInfo, ...queryParams }) : userAPI. list ({ ...pageInfo, ...queryParams }), rowKey : 'id' , deleteAPI : ( ids ) => userAPI. removeBatch (ids) }) 七、旧式RPC接口 vs RESTful新规范对照 适配老旧项目迁移改造,快速对齐新旧接口语义,方便统一项目接口风格 旧式RPC风格接口 标准化RESTful接口 GET /api/user/queryById?id=1 GET /api/users/1 GET /api/user/pageQueryList GET /api/users / POST /api/users/search POST /api/user/saveInsert POST /api/users POST /api/user/saveUpdate PUT /api/users/:id POST /api/user/delete DELETE /api/users/:id POST /api/user/batchDelete DELETE /api/users 补充适配方案 后端提供「新增表单默认值」接口 GET /api/users/new ,不属于基础CRUD,直接在业务API手动拓展即可,不改动基础封装代码。 八、项目自定义改造指南 1. 适配PATCH局部更新 后端使用PATCH做部分字段更新,在createBaseAPI内新增方法即可: /** PATCH 局部更新 */ patch ( id: string , data: Q[ 'update' ] ) { return http. patch ( ` ${baseUrl} / ${id} ` , data) } 2. 适配非标批量删除路径 后端批量删除为 POST /api/users/batch-del ,业务层直接拓展方法: // userAPI拓展自定义批量删除 userAPI. batchDel = ( ids: string [] ) => http. post ( '/api/users/batch-del' , { ids }) 3. 修改分页字段 后端分页参数不为page/size,直接修改PageParams全局类型即可全局生效。 九、总结 这套封装 零第三方依赖 ,依托项目原有axios请求实例,接入成本极低 区分GET简易查询 / POST复杂查询,完美解决URL超长、参数转义问题 泛型全覆盖,业务层只需定义实体类型,全程TS类型兜底,减少接口报错 基础CRUD零代码编写,非标接口灵活拓展,兼容新旧后端接口规范 后续新增任意业务模块(角色、菜单、字典),仅需3行代码即可生成全套CRUD接口,开发效率直接翻倍✨