TypeScript封装通用RESTful BaseAPI,后台接口代码精简80%

本文适用场景:Vue3+TS+Axios 中后台管理系统、遵循RESTful接口规范项目、大量同质化增删改查业务

阅读收益:一套可直接落地的通用CRUD封装、区分简易/复杂分页查询最佳实践、对接自定义表格Hook完整用法、RPC旧式接口迁移方案

前置依赖 :项目已封装全局axios请求实例 @/utils/http


一、项目痛点

开发中后台系统,绝大多数业务模块(用户、角色、菜单、商品、部门)接口高度同质化:分页列表、详情、新增、编辑、单删、批量删除。

传统写法存在大量问题:

  1. 每个业务模块重复手写7个基础请求方法,代码冗余、维护成本高
  2. 旧式RPC接口命名杂乱:queryPage、save、update、batchDelete,接口风格不统一
  3. 多条件筛选、日期区间、多选数组参数,GET请求超长导致接口报错
  4. 分页参数、返回体类型重复定义,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[]},表格多选删除

核心选型技巧

  1. 简单筛选:优先GET list,写法简洁、缓存友好

  2. 复杂筛选:必用POST search,避免浏览器URL长度限制、特殊参数转义问题

  3. 后端批量路径自定义:可手动扩展方法适配 /batch-delete 这类非标接口


三、核心工具类 createBaseAPI 源码

新建文件 @/utils/createBaseAPI.ts,完整类型封装,支持泛型约束,完美适配TS类型提示

typescript 复制代码
import { http } from '@/utils/http'

/** 后端统一分页返回结构体 */
export interface PageResult<T> {
  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<T, Q extends QueryMap = QueryMap>(params: { baseUrl: string }) {
  const { baseUrl } = params

  return {
    /** GET /resource/:id 获取详情 */
    getById(id: string) {
      return http.get<T>(`${baseUrl}/${id}`)
    },

    /** GET /resource 简易分页列表 */
    list(params: PageParams & Q['list']) {
      return http.get<PageResult<T>>(baseUrl, params)
    },

    /** POST /resource/search 复杂分页筛选 */
    search(params: PageParams & Q['list']) {
      return http.post<PageResult<T>>(`${baseUrl}/search`, params)
    },

    /** POST /resource 新增资源 */
    create(data: Q['create']) {
      return http.post<T>(baseUrl, data)
    },

    /** PUT /resource/:id 全量更新资源 */
    update(id: string, data: Q['update']) {
      return http.put<T>(`${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,非标接口单独拓展即可。

typescript 复制代码
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

php 复制代码
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表格。

typescript 复制代码
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内新增方法即可:

typescript 复制代码
/** PATCH 局部更新 */
patch(id: string, data: Q['update']) {
  return http.patch<T>(`${baseUrl}/${id}`, data)
}

2. 适配非标批量删除路径

后端批量删除为 POST /api/users/batch-del,业务层直接拓展方法:

typescript 复制代码
// userAPI拓展自定义批量删除
userAPI.batchDel = (ids: string[]) => http.post('/api/users/batch-del', { ids })

3. 修改分页字段

后端分页参数不为page/size,直接修改PageParams全局类型即可全局生效。


九、总结

  1. 这套封装零第三方依赖,依托项目原有axios请求实例,接入成本极低
  2. 区分GET简易查询 / POST复杂查询,完美解决URL超长、参数转义问题
  3. 泛型全覆盖,业务层只需定义实体类型,全程TS类型兜底,减少接口报错
  4. 基础CRUD零代码编写,非标接口灵活拓展,兼容新旧后端接口规范

后续新增任意业务模块(角色、菜单、字典),仅需3行代码即可生成全套CRUD接口,开发效率直接翻倍✨


相关推荐
胡永双1 小时前
Hexo + GitHub Pages搭建个人Blog教程(三)
前端
hunterandroid1 小时前
[Android 从零到一] 权限管理:运行时权限与最佳实践
前端
kyrie282 小时前
Redux 完整基础操作(原生 Redux,不结合 React-Redux)
前端
因_崔斯汀2 小时前
Vue 模板编译:HTML 是怎么变成 JS 的?
前端·vue.js
UXbot2 小时前
帮助企业低门槛开展AI应用开发的平台推荐
前端·低代码·ui·交互·产品经理·原型模式·web app
橘子星2 小时前
基于 Vite 的多模态生图前端工程实践
前端·javascript·人工智能
想要成为糕糕手2 小时前
从零到一:CSS 3D 旋转立方体完全指南
前端·css·canvas
疯狂的魔鬼2 小时前
多角色督办任务详情页:从权限矩阵到组件拆分的完整实现
前端·vue.js·架构
恋猫de小郭2 小时前
Android 17 正式版发布,全新 AI 和各种破坏性更新
android·前端·flutter