🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

if-service

Package Overview
Dependencies
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Potential malware was recently detected in this package.

Affected versions:

1.0.47-alpha.0

if-service

全局API服务

latest
npmnpm
Version
1.0.45
Version published
Weekly downloads
180
328.57%
Maintainers
1
Weekly downloads
 
Created
Source

if-service

if-service 是一个基于 axios 的轻量 API 服务注册库,适合把接口定义按模块统一管理,并补上网关切换、请求取消、结果缓存、状态监听等能力。

适用场景

  • 需要把接口按模块注册为 user.login()order.list() 这种调用方式
  • 需要根据环境自动拼接网关前缀
  • 需要统一请求头、鉴权策略和文件上传处理
  • 需要批量取消请求或监听 HTTP 状态码 / 业务码

安装

npm i if-service

如果你要使用 useApi() / usePager(),项目中还需要安装并提供 vue

快速开始

1. 初始化环境和网关

import IfService from "if-service";

app.use(IfService, {
  env: "local",
  gateway: {
    default: {
      local: "http://localhost:3000",
      production: "https://api.example.com",
    },
    admin: {
      local: "http://localhost:3100",
      production: "https://admin-api.example.com",
    },
  },
});

app.use() 本质上会调用内部的 createInstance({ env, gateway }),用于初始化当前运行环境和网关配置。

2. 注册接口

import { addService } from "if-service";

addService("user", "login", {
  url: "/auth/login",
  method: "post",
});

addService("user", "profile", {
  url: "/user/profile",
  method: "get",
});

3. 发起请求

import { useService } from "if-service";

const $ = useService("user");

const res = await $.login({
  username: "demo",
  password: "123456",
});

返回值约定

这是这个库最重要的行为约定,建议先看这一节。

  • 默认 JSON 请求成功时,返回的是 response.data,不是完整的 AxiosResponse
  • 二进制响应 arraybufferblobstream 时,返回原始 AxiosResponse
  • HTTP 非 2xx 时,拦截器会返回 err.response,默认不会进入 catch
  • 请求取消时,返回取消对象,也默认不会进入 catch
  • 每个实际发出的请求 Promise 都会挂一个 abort() 方法

也就是说,同一个接口在不同场景下可能拿到两种形态:

const $ = useService("user");
const res = await $.profile();

// 成功时通常是后端业务对象
// { code, message, data }

// 非 2xx 时通常是 AxiosResponse
// { status, data, headers, config, ... }

如果你要统一判断,推荐优先兼容 statuscode

const $ = useService("user");
const result = await $.profile();
const code = result?.status ?? result?.code;

核心 API

addService(module, apiName, options | url)

注册单个接口。

addService("user", "login", {
  url: "/auth/login",
  method: "post",
});

// 字符串写法等价于只传 url,method 默认 post
addService("user", "logout", "/auth/logout");

options 支持以下字段:

  • url: 接口地址,支持绝对地址、相对地址、:param 路径参数
  • method: get / post / put / delete / postget
  • gateway: 网关名称,默认空字符串;最终通过 getGateway() 拼接前缀
  • config: 请求配置对象
  • cache: false | true | string | function
  • expired: 缓存秒数,默认 1800
  • cacheMode: LocalStorage / Memory / ls
  • cacheAfterRequest: 缓存条件函数,默认 (res) => +res.code === 200

useService(module?)

读取已注册的服务。

const $ = useService("user");
await $.login({ username: "demo" });

const $$ = useService();
await $$.user.profile();

extendService(module, apis, options)

在同一个模块下批量注册接口。

import { extendService } from "if-service";

extendService("user", {
  login: "/auth/login@post",
  profile: "/user/profile@get",
  update: "/user/profile@put",
}, {
  gateway: "admin",
});

说明:

  • apis 的值格式为 url@method
  • options 中除 gateway / authMode 外,其余字段会进入 config

registerService(serviceMap, options)

批量注册多个模块,模块名支持带网关后缀。

import { registerService, useService } from "if-service";

registerService({
  user: {
    login: "/auth/login@post",
    profile: "/user/profile@get",
  },
  report@admin: {
    list: "/reports/list@post",
  },
});

const $ = useService("user");
const $$ = useService("report");

说明:

  • 模块键名为 module@gateway 时,会自动把该模块挂到对应网关
  • 没写 @gateway 时,默认走 default

API(options)

直接调用底层请求能力,不经过服务注册。

import { API } from "if-service";

const res = await API({
  url: "/health",
  method: "get",
  gateway: "default",
});

请求配置

config.headers

追加当前请求头:

addService("user", "profile", {
  url: "/user/profile",
  method: "get",
  config: {
    headers: {
      "x-trace-id": "demo",
    },
  },
});

config.authMode

支持两种模式:

  • "Bearer": 自动从 document.cookie 中读取 Authorization
  • function: 自定义返回请求头对象
addService("user", "profile", {
  url: "/user/profile",
  method: "get",
  config: {
    authMode: () => ({
      Authorization: "Bearer " + token,
    }),
  },
});

setGlobalAuthMode(fn)

设置全局鉴权头生成函数,所有请求都会合并其返回值。

import { setGlobalAuthMode } from "if-service";

setGlobalAuthMode(() => ({
  Authorization: "Bearer " + localStorage.getItem("token"),
}));

setCommonHeader(headers) / getCommonHeader()

维护全局公共请求头。

import { setCommonHeader } from "if-service";

setCommonHeader({
  "x-app-id": "web-console",
});

config.formData

把普通对象转成 FormData 发送:

const $ = useService("user");

$.saveProfile(
  { nickname: "demo", avatar: file },
  { config: { formData: true } }
);

config.file

用于文件上传,会强制设置 Content-Type: multipart/form-data,并把参数转为 FormData

$.upload(
  { file },
  { config: { file: true } }
);

路径参数

url 支持 :param 占位符,发请求时会从 params 中取值并替换,同时从原对象中移除该字段。

addService("project", "detail", {
  url: "/projects/:projectId",
  method: "get",
});

const $ = useService("project");
await $.detail({ projectId: 1 });
// 实际请求 /projects/1

网关与环境

createInstance({ env, gateway })

手动初始化环境和网关,不依赖 Vue 插件安装:

import { createInstance } from "if-service";

createInstance({
  env: "local",
  gateway: {
    default: {
      local: "http://localhost:3000",
      production: "https://api.example.com",
    },
  },
});

缓存

缓存发生在 addService() 注册的接口层。

addService("user", "profile", {
  url: "/user/profile",
  method: "get",
  cache: true,
  expired: 3600,
  cacheMode: "LocalStorage",
});

缓存规则:

  • cache: true 时,默认 key 为 module.apiName
  • cache: "custom-key" 时,使用自定义 key
  • cache: (module, apiName, params) => string 时,动态生成 key
  • 命中缓存后,接口会返回 Promise.resolve(cachedValue)
  • 默认只在 +res.code === 200 时写入缓存

请求取消与收集

单请求取消

const p = userService.profile();
p.abort();

useCollection()

创建一个请求收集器。创建之后发出的请求会被收集,支持统一取消。

import { useCollection } from "if-service";

const collection = useCollection();

userService.profile();
userService.detail({ id: 1 });

collection.abort();
collection.destroy();

说明:

  • abort(filterFn) 只取消符合条件的请求
  • destroy() 会取消全部请求并销毁当前收集器
  • 请求完成、失败或取消后会自动从收集器移除

abortRequests(filterFn?)

取消默认全局收集器中的请求:

import { abortRequests } from "if-service";

abortRequests((options) => options.url.includes("/user"));

Watcher

addWatcher() 用于监听 HTTP 状态码,或后端业务码。

监听固定状态码 / 业务码

import { addWatcher } from "if-service";

addWatcher(401, (source, response) => {
  console.log(source, response);
});

匹配规则:

  • 成功响应时,优先读取 response.data.code
  • 失败响应时,优先读取 response.status
  • 实际判断表达式是 source.status || source.code

监听自定义表达式

addWatcher(
  (code) => ![200, 401, 500].includes(+code),
  (source, response) => {
    console.log("unexpected response", source, response);
  }
);

说明:

  • 允许同一个 code 注册多个 watcher
  • 传函数时会注册到全局表达式 watcher 列表

Vue 辅助方法

useApi(module, api)

返回:

  • loader
  • error
  • data
  • query(params)
import { useApi } from "if-service";

const { loader, error, data, query } = useApi("user", "profile");
query();

usePager(module, api)

返回:

  • loader
  • error
  • data
  • pagination
  • query(page, initQuery)
import { usePager } from "if-service";

const { loader, error, data, pagination, query } = usePager("report", "list");
query(1, { keyword: "demo" });

注意:

  • 当前实现直接依赖 vueref / reactive
  • 这两个辅助方法对响应结构有假设,建议先确认你的后端返回格式与现有实现兼容
  • 如果你更关注稳定性,优先直接使用 useService()

调用时覆盖选项

服务调用时可以传第二个参数覆盖注册时配置:

userService.profile(
  {},
  {
    gateway: "admin",
    config: {
      headers: {
        "x-debug": "1",
      },
    },
  }
);

注意:

  • 这里是浅覆盖,不是深合并
  • 如果你传了新的 config,会整体替换注册时的 config

导出成员

运行时代码当前导出如下成员:

  • 默认导出:IfService Vue 插件对象
  • axios
  • API
  • addService
  • useService
  • useCollection
  • extendService
  • createInstance
  • setGlobalAuthMode
  • registerService
  • addWatcher
  • useApi
  • usePager
  • abortRequests
  • setCommonHeader
  • getCommonHeader

建议实践

  • 优先用 registerService()extendService() 维护接口映射
  • 统一通过 setGlobalAuthMode()setCommonHeader() 注入公共头
  • 对大列表页或切页场景,用 useCollection()abortRequests() 避免并发脏数据
  • 如果后端同时存在 HTTP 状态码和业务码,统一接入 addWatcher()

Keywords

axios

FAQs

Package last updated on 25 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts