马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
引言
本文旨在先容一种方法,用于在 typescript 和 axios 的项目中,有效的组合和管理大量的 API 接口以及 interface。
假如我们根据 API 文档对全部的接口做了初步分类,大体如下:
- scm(某业务模块)
- ├── inventory(库存业务)
- │ ├── warehouse # 仓库资源
- │ ├── material # 物料资源
- │ ├── unit # 计量单位资源
- │ └── ...
- ├── order(订单业务)
- │ ├── order # 订单资源
- │ ├── customer # 客户资源
- │ └── ...
- └── ...
复制代码 具体来说,对于单个但资源后端提供了一系列 CRUD 操作接口, 以warehouse为例:
类型方法&路径列表<GET /api/scm/warehouse/>创建< OST /api/scm/warehouse/>详情<GET /api/scm/warehouse/1/>整体更新< UT /api/scm/warehouse/1/>部分更新< ATCH /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) {
- // 添加token
- if (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();
复制代码 总结
对资源接口做好分类,将请求函数组织在合理的目录布局中,有助于进步代码的可维护性和可扩展性。同时对请求函数举行统一封装和组织,使得对请求的调用更加方便。
|