经验总结:typescript 和 axios 项目中大量接口该如何管理和组织

news/2024/10/30 7:04:10/

引言

本文旨在介绍一种方法,用于在 typescript 和 axios 的项目中,有效的组合和管理大量的 API 接口以及 interface。

假如我们根据 API 文档对所有的接口做了初步分类,大体如下:

scm(某业务模块)├── inventory(库存业务)│    ├── warehouse # 仓库资源│    ├── material  # 物料资源│    ├── unit      # 计量单位资源│    └── ...├── order(订单业务)│     ├── order    # 订单资源│     ├── customer # 客户资源│     └── ...└── ...

具体来说,对于单个但资源后端提供了一系列 CRUD 操作接口, 以warehouse为例:

类型方法&路径
列表<GET /api/scm/warehouse/>
创建<POST /api/scm/warehouse/>
详情<GET /api/scm/warehouse/1/>
整体更新<PUT /api/scm/warehouse/1/>
部分更新<PATCH /api/scm/warehouse/1/>
删除<DELETE /api/scm/warehouse/1/>

在项目中,我们会有大量的资源,每种资源又会产生很多接口,对接这些接口我们需要创建很多请求函数,因此如何管理这些请求函数变得尤为重要。本文将介绍一种高效的组织方法,话不多说,让我们开始吧。

一、封装 axios

我们不讨论对axios的深度封装,这里只做最简单的处理:

// utils/request.ts
import { useTokenStore } from "@/stores/auth/token";
import axios from "axios";// 后端API统一的返回结构
export type Result<T> = {status: string;code: number;message: string[];result: T;
};const tokenStore = useTokenStore();
const access = tokenStore.getToken.access;// 配置新建一个 axios 实例
const instance = axios.create({baseURL: import.meta.env.VITE_API_URL || "http://localhost:8000",timeout: 60000,
});// 添加请求拦截器
instance.interceptors.request.use(function (config) {// 添加tokenif (access) {config.headers.Authorization = `Bearer ${access}`;}return config;},function (error) {// 对请求错误做些什么return Promise.reject(error);}
);// 添加响应拦截器
instance.interceptors.response.use(function (response) {// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么return response;},function (error) {// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么return Promise.reject(error);}
);export default instance;

二、对接接口

在引言中我们介绍了所有的资源接口,以及其分类:

scm(某业务模块)├── inventory(库存业务)│    ├── warehouse # 仓库资源│    ├── material  # 物料资源│    ├── unit      # 计量单位资源│    └── ...├── order(订单业务)│     ├── order    # 订单资源│     ├── customer # 客户资源│     └── ...└── ...

根据分类,我们创建下面的目录接口来存放请求函数:

/vue-project
├── /src
│   └── /api
│        ├── ...
│        └── /scm
│            ├── inventory.ts  (示例所在)
│            ├── order.ts
│            ├── ...
│            └── index.ts

warehouse资源为例,我们要为其所有的资源操作接口创建请求方法、要为其所有接口的请求体和响应体创建interface

// .../scm/inventory.ts
import request, { type Result } from "@/utils/request";const baseUrl = "/api/scm";// 仓库接口
// ----------------------------------------------------
export interface WarehouseBaseIn {name: string;code: string;
}export interface WarehouseBaseOut {id: number;name: string;code: string;created_by: number;created_at: string;
}export interface WarehousePatchIn {name?: string;code?: string;
}export const warehouse = {list: () =>// 获取列表request<Result<WarehouseBaseOut[]>>({url: baseUrl + "/warehouse/",method: "GET",}),create: (data: WarehouseBaseIn) =>// 创建request<Result<WarehouseBaseOut[]>>({url: baseUrl + "/warehouse/",method: "POST",data,}),retrieve: (id: string) =>// 按ID查询request<Result<WarehouseBaseOut[]>>({url: baseUrl + `/warehouse/${id}/`,method: "GET",}),put: (id: string, data: WarehouseBaseIn) =>// 全部更新request<Result<WarehouseBaseOut[]>>({url: baseUrl + `/warehouse/${id}/`,method: "PUT",data,}),patch: (id: string, data: WarehousePatchIn) =>// 部分更新request<Result<WarehouseBaseOut[]>>({url: baseUrl + `/warehouse/${id}/`,method: "PATCH",data,}),destroy: (id: string) =>// 删除request<Result<any>>({url: baseUrl + `/warehouse/${id}/`,method: "Delete",}),
};// 除了warehouse之外,inventory文件中实际上还会有更多的接口。
// 比如: material、unit等等,封装的方法都是类似的。
// ...

对单个资源的封装可以总结为如下结构:

const source = {list: function...,create: function...,retrieve: function...,put: function...,patch: function...,destroy: function...
}

回顾我们的目录结构:

/vue-project
├── /src
│   └── /api
│        ├── ...
│        └── /scm
│            ├── inventory.ts   (示例所在)
│            ├── order.ts
│            ├── ...
│            └── index.ts

上述的目录结构,使得我们可以对大量的资源进行分类组织,而为了方便请求函数调用,我们还需要在index.ts中对请求函数进行汇总。

// .../scm/index.ts
import { warehouse, material, unit,... } from './inventory'
import { order, customer, ... } from './order'const api = {inventory: {warehouse,material,unit,...},order: {order,customer,...}
}export default api

使用方法如下,并且能够充分得到 ide 提示:

import api from "@/api/scm";// 使用.时ide的提示会很友好
api.inventory.warehouse.list();
api.inventory.material.list();
api.order.customer.list();
api.order.order.list();

总结

对资源接口做好分类,将请求函数组织在合理的目录结构中,有助于提高代码的可维护性和可扩展性。同时对请求函数进行统一封装和组织,使得对请求的调用更加方便。


http://www.ppmy.cn/news/1543029.html

相关文章

使用 Kafka 和 MinIO 实现人工智能数据工作流

MinIO Enterprise Object Store 是用于创建和执行复杂数据工作流的基础组件。此事件驱动功能的核心是使用 Kafka 的 MinIO 存储桶通知。MinIO Enterprise Object Store 为所有 HTTP 请求&#xff08;如 PUT、POST、COPY、DELETE、GET、HEAD 和 CompleteMultipartUpload&#xf…

保持HTTP会话状态:缓存策略与实践

在互联网技术领域&#xff0c;保持HTTP会话状态对于提供连贯和个性化的用户体验至关重要。本文将深入探讨HTTP会话状态的缓存策略&#xff0c;并提供实践指南和代码实现&#xff0c;包括如何在代码中添加代理信息以增强安全性和隐私保护。 HTTP会话状态的重要性 HTTP协议本身…

基于随机森林的智能手机用户行为分类及流量预测分析

1.项目背景 随着智能手机的快速发展&#xff0c;消费者对智能手机的使用行为和习惯也日趋多样化。特别是在5G时代的到来和各类应用的丰富发展背景下&#xff0c;智能手机使用模式呈现出新的特点&#xff0c;本项目使用模拟生成的700位用户智能手机使用数据进行深入分析&#x…

PHP内存马:不死马

内存马概念 内存马是无文件攻击的一种常用手段&#xff0c;利用中间件的进程执行某些恶意代码。首先要讲的是PHP不死马&#xff0c;实质上就是直接用代码弄一个死循环&#xff0c;强占一个 PHP 进程&#xff0c;并不间断的写一个PHP shell&#xff0c;或者执行一段代码。 不死…

HTML入门教程2:HTML发展历史

HTML的诞生 起源时间&#xff1a;1989年创始人&#xff1a;蒂姆伯纳斯-李&#xff08;Tim Berners-Lee&#xff09; HTML最初由蒂姆伯纳斯-李在CERN&#xff08;欧洲核子研究中心&#xff09;提出。当时&#xff0c;互联网正处于萌芽阶段&#xff0c;伯纳斯-李为了实现全球科…

微服务设计模式 - 重试模式(Retry Pattern)

微服务设计模式 - 重试模式&#xff08;Retry Pattern&#xff09; 定义 重试模式&#xff08;Retry Pattern&#xff09;是一种微服务中的设计模式&#xff0c;用于在临时性失败&#xff08;如网络故障或暂时不可用的服务&#xff09;发生时&#xff0c;自动重新尝试请求&…

Depcheck——专门用于检测 JavaScript 和 Node.js 项目中未使用依赖项的工具

文章目录 Depcheck 是什麽核心功能&#x1f4da;检测未使用的依赖&#x1f41b;检测缺失的依赖✨支持多种文件类型&#x1f30d;可扩展性 安装与使用1. 安装 Depcheck2. 使用 Depcheck Depcheck 的应用总结项目源码&#xff1a; Depcheck 是什麽 来看一个常见错误场景&#x1…

[实时计算flink]使用Python依赖

您可以在Flink Python作业中使用自定义的Python虚拟环境、第三方Python包、JAR包和数据文件等&#xff0c;本文为您介绍如何在Python作业中使用这些依赖。 使用自定义的Python虚拟环境 说明 VVR 4.x仅支持3.7版本的Python虚拟环境&#xff0c;VVR 6.x及以上的版本无此限制&a…