Skip to content

扩展 API 层

添加接口有三种方式,按复用范围选择:

场景方式
后台管理接口,多端复用加到 @fx/api-admin
全新业务域(前台 H5 等),独立复用新建 @fx/api-{域} 包
仅当前项目用,不需要复用业务层直接加

一、在 @fx/api-admin 加接口

新增一个业务域(以 products 为例)

1. 创建业务文件 —— packages/api/admin/src/products.ts类型与接口就近定义

ts
import type { HttpRequest, PageResult } from "@fx/api-core"

/** 产品信息 */
export interface ProductItem {
  id: number
  name: string
  price: number
  status: number
  created_at: string
  updated_at: string
}

export function createProductsApi(http: HttpRequest) {
  return {
    getProducts: (params?: { page?: number; page_size?: number }) =>
      http.get<PageResult<ProductItem>>("/api/v1/sys/products", { params }),
    createProduct: (data: { name: string; price: number }) =>
      http.post<ProductItem>("/api/v1/sys/products", data),
    deleteProduct: (id: number) => http.delete(`/api/v1/sys/products/${id}`),
  }
}

2. 注册 —— packages/api/admin/index.ts:导入工厂并在 createAdminApi 聚合,同时 re-export 类型:

ts
import { createProductsApi } from "./src/products"

export function createAdminApi(http: HttpRequest) {
  return {
    // ...现有
    products: createProductsApi(http),
  }
}

// 类型 re-export:消费方可 import type { ProductItem } from "@fx/api-admin"
export type { ProductItem } from "./src/products"

3. 消费方使用(无需改 admin-instance):

ts
adminApi.products.getProducts({ page: 1 })

在现有域加方法

在对应文件(如 src/users.ts)的工厂返回对象里追加即可,无需改 index.ts:

ts
export function createUsersApi(http: HttpRequest) {
  return {
    // ...现有
    exportUsers: () => http.get("/api/v1/sys/users/export"),
  }
}

二、新建 @fx/api-{域} 包

适用于与后台管理不同业务域(如前台 H5 的经期/用户接口),与 @fx/api-admin 平级、各管各的。

1. 创建包

packages/api/web-h5/
  ├─ package.json
  ├─ index.ts          createWebH5Api(http) 工厂 + 类型 re-export
  └─ src/
      ├─ period.ts      PeriodItem + createPeriodApi(http)
      └─ ...

package.json

json
{
  "name": "@fx/api-web-h5",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "exports": { ".": { "import": "./index.ts" } },
  "dependencies": { "@fx/api-core": "workspace:*" }
}

index.ts(结构与 @fx/api-admin 一致:工厂聚合 + 类型 re-export + core 转发):

ts
import type { HttpRequest } from "@fx/api-core"
import { createPeriodApi } from "./src/period"

export function createWebH5Api(http: HttpRequest) {
  return { period: createPeriodApi(http) /* ... */ }
}

// 类型就近定义在各业务文件,index 仅 re-export
export type { PeriodItem } from "./src/period"

// core 转发(消费方只需引 @fx/api-web-h5)
export { createHttp, createRawClient } from "@fx/api-core"

2. 消费方接入

在 web-h5 项目里用自己的 http 实例创建(与 web 接入 @fx/api-admin 完全同理):

ts
import { createWebH5Api } from "@fx/api-web-h5"
import { request } from "./request" // 该项目的 createHttp 实例
export const webH5Api = createWebH5Api(request)

与 @fx/api-admin 的关系

两者平级独立(互不依赖),都基于 @fx/api-core。一个消费方若同时需要后台与前台接口,可各自 createAdminApi(http) + createWebH5Api(http),共用同一个 http 实例。

三、业务层直接加接口

只在当前项目用、不需要跨项目复用的接口,直接在项目内创建,不进共享包。

web 内加接口

新建 web/src/api/custom.ts,直接用 web 的 requestcreateHttp 实例,自动带 token / 拦截器 / 401 刷新):

ts
import { request } from "./request"

/** 自定义接口(仅 web 用,不进共享包) */
export function getCustom() {
  return request.get<CustomItem>("/api/v1/sys/custom")
}

export function doCustom(id: number, data: CustomData) {
  return request.post(`/api/v1/sys/custom/${id}/do`, data)
}

页面调用:

ts
import { getCustom } from "@/api/custom"
const { data } = await getCustom()

request 与 adminApi 共用同一实例

request 就是 adminApi 内部使用的那个 http(createAdminApi(request)),两者发请求走同一套拦截器/401 刷新。所以业务层接口用 request 和用 adminApi 行为一致,只是不归共享包管理。

通用约定

约定说明
URL 前缀统一 /api/v1/sys/ 开头,与后端路由对齐
类型位置就近定义在对应业务文件(如 ProductItemsrc/products.ts),index.ts 仅 re-export;业务层类型放项目内
工厂命名create{域}Api,如 createProductsApi
通用类型HttpRequest / PageResult / ApiResponse@fx/api-core 引入
响应解包http.get/post 已自动解包,返回 Promise<ApiResponse<T>>,用 const { data } = await ...