aptx-api-core

创建、配置或扩展 HTTP 客户端时使用。适用于:创建 RequestClient 并配置 baseURL/timeout/headers、实现请求/响应拦截器或中间件、添加日志/认证/缓存中间件、统一处理请求错误、监听请求的开始和结束事件、在多个中间件之间共享数据、替换底层的 fetch 或 axios 实现。当用户需要封装 HTTP 请求工具类、实现请求拦截、处理请求超时或构建 API 客户端时,即使未提及具体包名也应触发。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "aptx-api-core" with this command: npx skills add haibaraaiaptx/aptx-skill/haibaraaiaptx-aptx-skill-aptx-api-core

aptx-api-core

在需要接入或调整请求内核时,按以下顺序执行:

  1. 创建 RequestClient,先确定全局配置:baseURLheaderstimeoutquerySerializerdefaultResponseTypestrictDecode。详见 实例化配置
  2. 只在 @aptx/api-core 层处理通用行为,不引入业务认证、缓存、重试逻辑。业务逻辑应通过 MiddlewarePlugin 实现。
  3. 通过 use(middleware)apply(plugin) 扩展能力,确保核心逻辑保持纯净。详见 扩展能力
  4. 使用 request:start/end/error/abort 事件做观测,不在事件回调里修改 payload。详见 事件系统
  5. 发生错误时按错误类型分流:HttpErrorNetworkErrorTimeoutErrorCanceledErrorConfigErrorSerializeErrorDecodeError。详见 defaults.md - ErrorMapper

最小接入模板:

import { RequestClient } from "@aptx/api-core";

const client = new RequestClient({
  baseURL: "/api",
  timeout: 10_000,
  headers: { "X-App": "web" },
  defaultResponseType: "json",
});

const res = await client.fetch("/user", {
  method: "GET",
  query: { include: ["profile", "roles"] },
});

快速参考

操作API示例
创建客户端new RequestClient()见上方模板
创建客户端(函数式)createClient()创建客户端工厂函数
发送请求client.fetch()await client.fetch("/user", { method: "GET" })
发送请求(高级)client.request()request() - 高级入口
添加 middlewareclient.use()client.use(loggingMiddleware)
应用 pluginclient.apply()client.apply(authPlugin)
监听事件client.events.on()事件系统

核心 API 映射

需求方法文档位置
请求/响应修改Middlewaremiddleware-patterns.md
替换核心组件Pluginplugin-patterns.md
中间件间共享状态Context Bagcontext-bag.md
自定义传输/解码器等Extension Pointsextension-points.md
错误拦截(HTTP 状态码)Middleware try/catchmiddleware-patterns.md#9
错误拦截(业务逻辑)Middleware 后置检查middleware-patterns.md#8
测试扩展Testingtesting-guide.md
查看默认实现Defaultsdefaults.md

请求元数据

RequestMeta 用于传递扩展元数据:

interface RequestMeta {
  /** 响应类型(覆盖默认值) */
  responseType?: "json" | "text" | "blob" | "arrayBuffer" | "raw";
  /** 自定义标签(用于追踪、日志等) */
  tags?: string[];
  /** 上传进度回调(best-effort) */
  onUploadProgress?: (info: ProgressInfo) => void;
  /** 下载进度回调(best-effort) */
  onDownloadProgress?: (info: ProgressInfo) => void;
  /** 其他扩展字段 */
  [key: string]: unknown;
}

进度回调(best-effort)

await client.fetch("/upload", {
  method: "POST",
  body: largeFile,
  meta: {
    onUploadProgress: ({ loaded, total, progress }) => {
      console.log(`Upload: ${(progress! * 100).toFixed(1)}%`);
    },
  },
});

约束

  • 进度回调仅在 FetchTransport 中生效
  • 需要服务端返回 Content-Length
  • 仅作为 best-effort 功能,不保证精确性

显式响应类型

// 文本响应
const res = await client.fetch("/data", {
  meta: { responseType: "text" },
});

// Blob 响应(文件下载)
const blobRes = await client.fetch("/file.pdf", {
  meta: { responseType: "blob" },
});

实例化配置

RequestClient 构造函数支持以下配置选项:

import {
  RequestClient,
  Transport,
  UrlResolver,
  BodySerializer,
  ResponseDecoder,
  ErrorMapper,
  Middleware,
  EventBus,
} from "@aptx/api-core";

const client = new RequestClient({
  // 基础配置
  baseURL: "https://api.example.com",
  headers: { "X-App": "web" },
  timeout: 10_000,
  querySerializer: (query, url) => `${url}?${new URLSearchParams(query).toString()}`,
  meta: { tags: ["api"] }, // 默认 meta

  // 响应配置
  defaultResponseType: "json",
  strictDecode: true, // 严格 JSON 解码

  // 核心组件(可自定义)
  transport?: Transport,        // 底层传输层
  urlResolver?: UrlResolver,    // URL 解析
  bodySerializer?: BodySerializer, // 请求体序列化
  decoder?: ResponseDecoder,    // 响应解码
  errorMapper?: ErrorMapper,    // 错误映射
  events?: EventBus,            // 事件总线

  // 扩展
  middlewares?: Middleware[],   // 初始 middleware 列表
});

详见 defaults.md 了解所有默认实现的详细说明和最佳实践。

fetch() vs request()

fetch() - fetch-like 入口

适用于大多数场景,自动处理 URL 解析和请求构建。

const res = await client.fetch("/user", {
  method: "GET",
  headers: { "X-Custom": "value" },
  query: { id: 123 },
  body: { name: "test" },
  timeout: 5000,
});

request() - 高级入口

适用于需要手动构建 Request 对象的场景:

import { Request } from "@aptx/api-core";

const req = new Request({
  method: "POST",
  url: "/api/data",
  headers: { "Content-Type": "application/json" },
  body: { key: "value" },
  timeout: 5000,
  meta: { tags: ["important"] },
});

const res = await client.request(req);

选择指南

需求选择原因
简单请求fetch()API 简洁,自动处理 URL 解析
需要复用 Request 对象request()更灵活,Request 对象可传递
需要在 middleware 间传递状态request()Request 对象可携带更多信息,详见 context-bag.md
需要显式控制请求构建request()完全控制 Request 创建过程

约束:

  • 不把重试、认证、CSRF 写进 core;统一放插件层。
  • headers: { key: null } 表示删除 header。
  • onUploadProgressonDownloadProgress 仅在支持的 transport 中生效。

响应元数据

ResponseMeta 用于在 middleware/plugin 间传递响应扩展信息:

interface ResponseMeta {
  /** 例如:{ fromCache: true } 由缓存 middleware 设置 */
  [key: string]: unknown;
}

使用示例(缓存 middleware)

const cacheMiddleware: Middleware = {
  async handle(req, ctx, next) {
    const cached = cache.get(req.url);
    if (cached) {
      return new Response({
        status: 200,
        headers: new Headers(),
        url: req.url,
        data: cached.data,
        raw: {},
        meta: { fromCache: true, cachedAt: cached.at },
      });
    }

    const res = await next(req, ctx);
    cache.set(req.url, res);
    return res;
  }
};

详见 middleware-patterns.md 了解更多缓存实现模式。

扩展能力

Middleware - 请求/响应修改

Middleware 用于处理横切关注点,如日志、认证、重试等。详见 middleware-patterns.md

创建自定义 middleware:

import { Middleware, Request, Context, Response } from "@aptx/api-core";

const loggingMiddleware: Middleware = {
  async handle(req, ctx, next) {
    console.log(`[${req.method}] ${req.url}`);
    const res = await next(req, ctx);
    console.log(`[${res.status}] ${req.url}`);
    return res;
  }
};
client.use(loggingMiddleware);

常见 Middleware 模式:

Plugin - 核心组件替换

Plugin 用于替换核心组件或监听事件。详见 plugin-patterns.md

使用场景:

Context Bag - 中间件间共享状态

使用 ctx.bag 在 middleware 间安全地共享状态。详见 context-bag.md

关键用法:

测试扩展

详见 testing-guide.md 学习如何测试 middleware 和 plugin。

事件系统

支持以下事件:

事件名Payload触发时机
request:start{ req, ctx }请求开始
request:end{ req, res, ctx, durationMs, attempt }请求成功
request:error{ req, error, ctx, durationMs, attempt }请求失败(不包括 abort)
request:abort{ req, ctx, durationMs }请求被中止

使用示例

client.events.on("request:start", ({ req, ctx }) => {
  console.log(`[${ctx.id}] START ${req.method} ${req.url}`);
});

client.events.on("request:end", ({ req, res, ctx, durationMs, attempt }) => {
  console.log(`[${ctx.id}] END ${res.status} ${req.url} (${durationMs}ms, attempt ${attempt})`);
});

client.events.on("request:error", ({ req, error, ctx, durationMs, attempt }) => {
  console.error(`[${ctx.id}] ERROR ${req.url} (${durationMs}ms)`, error);
});

client.events.on("request:abort", ({ req, ctx, durationMs }) => {
  console.warn(`[${ctx.id}] ABORT ${req.url} (${durationMs}ms)`);
});

详见 defaults.md 了解事件总线的完整实现。

创建客户端工厂函数

createClient()new RequestClient() 的别名:

import { createClient } from "@aptx/api-core";

const client = createClient({
  baseURL: "/api",
  timeout: 10_000,
});

适用于偏好函数式编程的场景。

常见问题

详见 faq.md 查看完整 FAQ,包括:

  • Request headers 没有被修改?
  • Progress 回调没有触发?
  • 如何区分超时和用户取消?
  • 如何防止 auth middleware 无限重试?
  • 何时使用 Middleware vs Plugin?
  • 如何在 middleware 间共享数据?
  • 如何测试自定义 middleware?
  • Response 数据类型不对怎么办?
  • 如何自定义 JSON 序列化?

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

aptx-api-plugin-retry

No summary provided by upstream source.

Repository SourceNeeds Review
General

aptx-api-plugin-csrf

No summary provided by upstream source.

Repository SourceNeeds Review
General

aptx-api-plugin-auth

No summary provided by upstream source.

Repository SourceNeeds Review
General

aptx-token-store

No summary provided by upstream source.

Repository SourceNeeds Review