api-examples.md 23 KB

# 前端 API 调用示例文档

目录


1. 概述

本项目后端提供三个平台的 API 代理服务,统一挂载在 /api/ 路径下:

平台 路径前缀 说明
Amazon SP-API /api/amazon/ 亚马逊卖家平台 API,涵盖订单、商品、销售、目录等模块
Sorftime API /api/sorftime/ Sorftime 数据分析平台,提供类目、产品、关键词、监控等功能
TikHub API /api/tikhub/ TikTok 数据平台,提供用户、视频、电商、广告等数据查询

⭐ 标记表示常用接口,建议优先了解。


2. 通用说明

2.1 基础 URL

https://server-msq.fmode.cn

本地开发环境可使用 http://localhost:10003,生产环境统一使用 HTTPS 域名。

2.2 认证方式

平台 认证 Header 必填 说明
Amazon SP-API shop-objectId Parse 数据库中 Shop 对象的 ObjectId,后端通过它查询店铺的 SP-API 凭证
Sorftime API 无需额外认证 后端已内置 API Token
TikHub API 无需额外认证 后端已内置 API Key

2.3 响应格式

所有接口统一返回 JSON 格式,通用结构如下:

interface ApiResponse<T = any> {
  success: boolean;   // 是否成功
  data: T;            // 业务数据
  timestamp: string;  // 时间戳
}

2.4 通用请求工具封装

建议在项目中封装统一的请求工具,以下为 axios 封装示例:

import axios, { AxiosInstance } from 'axios';

const BASE_URL = 'https://server-msq.fmode.cn';

// Amazon 请求实例
export const amazonClient: AxiosInstance = axios.create({
  baseURL: `${BASE_URL}/api/amazon`,
  headers: { 'Content-Type': 'application/json' },
});

// 设置店铺 ObjectId(Parse 数据库中 Shop 对象的 ObjectId)
export function setShopObjectId(shopObjectId: string): void {
  amazonClient.defaults.headers.common['shop-objectId'] = shopObjectId;
}

// Sorftime 请求实例(后端已内置 Token,无需前端传入)
export const sorftimeClient: AxiosInstance = axios.create({
  baseURL: `${BASE_URL}/api/sorftime`,
  headers: { 'Content-Type': 'application/json' },
});

// TikHub 请求实例(后端已内置 API Key,无需前端传入)
export const tikhubClient: AxiosInstance = axios.create({
  baseURL: `${BASE_URL}/api/tikhub`,
  headers: { 'Content-Type': 'application/json' },
});

2.5 错误处理

axios 错误处理示例(拦截器)

amazonClient.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response) {
      const status = error.response.status;
      switch (status) {
        case 400: console.error('请求参数错误'); break;
        case 401: console.error('认证失败,请检查 shop-objectId'); break;
        case 403: console.error('权限不足'); break;
        case 429: console.error('请求过于频繁,请稍后重试'); break;
        case 500: console.error('服务器内部错误'); break;
      }
    }
    return Promise.reject(error);
  }
);

3. Amazon SP-API

所有 Amazon 接口均需在请求头中携带 shop-objectId(Parse 数据库中 Shop 对象的 ObjectId)。 测试接口 /test 除外,无需认证。

3.1 测试接口

GET /api/amazon/test

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/amazon/test');
const data = await res.json();

// axios
const { data } = await amazonClient.get('/test');

响应示例:

{
  "success": true,
  "data": { "message": "SP-API 路由测试成功" },
  "timestamp": "2025-01-01T12:00:00.000Z"
}

3.2 客户反馈 (Customer Feedback)

GET /api/amazon/customerFeedback/items/:asin/reviews/topics — 商品评论主题

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/amazon/customerFeedback/items/B0EXAMPLE1/reviews/topics', {
  headers: { 'shop-objectId': 'your-shop-object-id' }
});

// axios
const { data } = await amazonClient.get('/customerFeedback/items/B0EXAMPLE1/reviews/topics');

GET /api/amazon/customerFeedback/items/:asin/browseNode — 商品浏览节点

const { data } = await amazonClient.get('/customerFeedback/items/B0EXAMPLE1/browseNode');

GET /api/amazon/customerFeedback/browseNodes/:browseNodeId/reviews/topics — 浏览节点评论主题

const { data } = await amazonClient.get('/customerFeedback/browseNodes/12345/reviews/topics');

GET /api/amazon/customerFeedback/items/:asin/reviews/trends — 商品评论趋势

const { data } = await amazonClient.get('/customerFeedback/items/B0EXAMPLE1/reviews/trends');

GET /api/amazon/customerFeedback/browseNodes/:browseNodeId/reviews/trends — 浏览节点评论趋势

const { data } = await amazonClient.get('/customerFeedback/browseNodes/12345/reviews/trends');

GET /api/amazon/customerFeedback/browseNodes/:browseNodeId/returns/topics — 浏览节点退货主题

const { data } = await amazonClient.get('/customerFeedback/browseNodes/12345/returns/topics');

GET /api/amazon/customerFeedback/browseNodes/:browseNodeId/returns/trends — 浏览节点退货趋势

const { data } = await amazonClient.get('/customerFeedback/browseNodes/12345/returns/trends');

3.3 订单 (Orders) ⭐

GET /api/amazon/orders — 获取订单列表

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/amazon/orders?MarketplaceIds=ATVPDKIKX0DER&CreatedAfter=2025-01-01T00:00:00Z', {
  headers: { 'shop-objectId': 'your-shop-object-id' }
});

// axios
const { data } = await amazonClient.get('/orders', {
  params: {
    MarketplaceIds: 'ATVPDKIKX0DER',
    CreatedAfter: '2025-01-01T00:00:00Z',
    CreatedBefore: '2025-01-31T23:59:59Z',
    OrderStatuses: 'Shipped'
  }
});

GET /api/amazon/orders/:orderId — 获取订单详情

const { data } = await amazonClient.get('/orders/111-1234567-1234567');

GET /api/amazon/orders/:orderId/items — 获取订单商品明细

const { data } = await amazonClient.get('/orders/111-1234567-1234567/items', {
  params: { NextToken: 'optional-pagination-token' }
});

3.4 销售 (Sales) ⭐

GET /api/amazon/sales/orderMetrics — 获取销售指标

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/amazon/sales/orderMetrics?marketplaceIds=ATVPDKIKX0DER&interval=2025-01-01T00:00:00Z--2025-01-31T23:59:59Z&granularity=Day', {
  headers: { 'shop-objectId': 'your-shop-object-id' }
});

// axios
const { data } = await amazonClient.get('/sales/orderMetrics', {
  params: {
    marketplaceIds: 'ATVPDKIKX0DER',
    interval: '2025-01-01T00:00:00Z--2025-01-31T23:59:59Z',
    granularity: 'Day'
  }
});

3.5 商品列表 (Listings) ⭐

GET /api/amazon/listings/items/:sellerId — 搜索卖家 Listing 列表

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/amazon/listings/items/A1EXAMPLE?marketplaceIds=ATVPDKIKX0DER', {
  headers: { 'shop-objectId': 'your-shop-object-id' }
});

// axios
const { data } = await amazonClient.get('/listings/items/A1EXAMPLE', {
  params: {
    marketplaceIds: 'ATVPDKIKX0DER',
    pageSize: 20
  }
});

GET /api/amazon/listings/items/:sellerId/:sku — 获取单个 Listing 详情

const { data } = await amazonClient.get('/listings/items/A1EXAMPLE/WH-BT-001', {
  params: { marketplaceIds: 'ATVPDKIKX0DER' }
});

PUT /api/amazon/listings/items/:sellerId/:sku — 更新 Listing

const { data } = await amazonClient.put('/listings/items/A1EXAMPLE/WH-BT-001', {
  productType: 'HEADPHONES',
  attributes: {
    item_name: [{ value: 'Updated Product Title' }]
  }
}, {
  params: { marketplaceIds: 'ATVPDKIKX0DER' }
});

DELETE /api/amazon/listings/items/:sellerId/:sku — 删除 Listing

const { data } = await amazonClient.delete('/listings/items/A1EXAMPLE/WH-BT-001', {
  params: { marketplaceIds: 'ATVPDKIKX0DER' }
});

3.6 外部履约 (External Fulfillment)

GET /api/amazon/externalFulfillment/returns — 获取退货列表

const { data } = await amazonClient.get('/externalFulfillment/returns', {
  params: {
    MarketplaceId: 'ATVPDKIKX0DER',
    Status: 'Open'
  }
});

GET /api/amazon/externalFulfillment/returns/:returnId — 获取退货详情

const { data } = await amazonClient.get('/externalFulfillment/returns/RET-12345');

3.7 目录 (Catalog Items) ⭐

GET /api/amazon/catalog/categories — 获取目录分类

const { data } = await amazonClient.get('/catalog/categories', {
  params: {
    MarketplaceId: 'ATVPDKIKX0DER',
    ASIN: 'B0EXAMPLE1'
  }
});

GET /api/amazon/catalog/items — 搜索目录商品

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/amazon/catalog/items?keywords=wireless+earbuds&marketplaceIds=ATVPDKIKX0DER', {
  headers: { 'shop-objectId': 'your-shop-object-id' }
});

// axios
const { data } = await amazonClient.get('/catalog/items', {
  params: {
    keywords: 'wireless earbuds',
    marketplaceIds: 'ATVPDKIKX0DER',
    includedData: 'summaries,images,salesRanks'
  }
});

GET /api/amazon/catalog/items/:asin — 获取商品详情

const { data } = await amazonClient.get('/catalog/items/B0EXAMPLE1', {
  params: {
    marketplaceIds: 'ATVPDKIKX0DER',
    includedData: 'summaries,images,salesRanks,dimensions,relationships'
  }
});

3.8 卖家 (Sellers)

GET /api/amazon/sellers/account — 获取卖家账户信息

const { data } = await amazonClient.get('/sellers/account');

GET /api/amazon/sellers/marketplaceParticipations — 获取市场参与信息

const { data } = await amazonClient.get('/sellers/marketplaceParticipations');

3.9 通用转发 (Forward)

通用转发接口可以调用任意亚马逊 SP-API 端点,适用于上述封装接口未覆盖的场景。支持 functionId 参数触发 Parse 云函数对返回数据做后处理。

POST /api/amazon/forward

请求参数:

参数 类型 必填 说明
path string SP-API 路径,如 /orders/v0/orders
method string HTTP 方法,默认 GET
query object 查询参数
body object 请求体
functionName string 自定义转换函数名
functionId string Parse 云函数 ID,提供后会执行云函数处理返回数据
// 基本用法 — 获取订单
const { data } = await amazonClient.post('/forward', {
  path: '/orders/v0/orders',
  method: 'GET',
  query: {
    MarketplaceIds: 'ATVPDKIKX0DER',
    CreatedAfter: '2025-01-01T00:00:00Z'
  }
});

// 带云函数后处理 — 获取订单并执行云函数清洗数据
const { data: processed } = await amazonClient.post('/forward', {
  path: '/orders/v0/orders',
  method: 'GET',
  query: { MarketplaceIds: 'ATVPDKIKX0DER' },
  functionId: 'RFDDkJ2usG'
});
// 响应包含 { apiResult: {...}, cloudFunctionResult: {...} }

Angular HttpClient 调用示例:

// Angular 中的典型调用方式
this.http.post('https://server-msq.fmode.cn/api/amazon/forward', {
  path: '/orders/v0/orders/${orderId}',
  functionId: 'RFDDkJ2usG'
}, {
  headers: { 'shop-objectId': this.shopId }
}).subscribe(res => {
  console.log(res);
});

带 functionId 的响应示例:

{
  "success": true,
  "data": {
    "apiResult": { "...亚马逊原始返回..." },
    "cloudFunctionResult": { "...云函数处理后的数据..." }
  },
  "timestamp": "2025-01-01T12:00:00.000Z"
}

4. Sorftime API

Sorftime 的 API Token 已在后端配置,前端无需传入认证信息。 所有 Sorftime 数据查询通过 /api/sorftime/forward 转发接口完成。

4.1 测试与健康检查

GET /api/sorftime/test — 测试接口

const res = await fetch('https://server-msq.fmode.cn/api/sorftime/test');
const data = await res.json();
// { "message": "Sorftime API Router Loaded Successfully v0.0.1" }

GET /api/sorftime/health — 健康检查

const res = await fetch('https://server-msq.fmode.cn/api/sorftime/health');
const data = await res.json();
// { "service": "sorftime", "timestamp": "2025-01-01T12:00:00.000Z" }

4.2 通用转发 (Forward) ⭐

Sorftime 所有数据查询均通过 forward 接口转发。支持 functionId 参数触发 Parse 云函数做后处理。

POST /api/sorftime/forward

请求参数:

参数 类型 必填 说明
path string Sorftime API 路径,如 /api/CategoryTree
method string HTTP 方法,默认 POST
query object 查询参数
body object 请求体
function string 自定义转换函数名
functionId string Parse 云函数 ID

示例:查询类目树

// axios
const { data } = await sorftimeClient.post('/forward', {
  path: '/api/CategoryTree',
  body: { domain: 'amazon.com' }
});

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/sorftime/forward', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    path: '/api/CategoryTree',
    body: { domain: 'amazon.com' }
  })
});

示例:查询产品数据

const { data } = await sorftimeClient.post('/forward', {
  path: '/api/ProductQuery',
  body: {
    domain: 'amazon.com',
    keyword: 'wireless earbuds',
    page: 1,
    pageSize: 20
  }
});

示例:查询产品详情

const { data } = await sorftimeClient.post('/forward', {
  path: '/api/ProductRequest',
  body: {
    domain: 'amazon.com',
    asin: 'B0EXAMPLE1'
  }
});

示例:关键词查询

const { data } = await sorftimeClient.post('/forward', {
  path: '/api/KeywordQuery',
  body: {
    domain: 'amazon.com',
    keyword: 'wireless earbuds'
  }
});

示例:ASIN 反查关键词

const { data } = await sorftimeClient.post('/forward', {
  path: '/api/ASINRequestKeyword',
  body: {
    domain: 'amazon.com',
    asin: 'B0EXAMPLE1'
  }
});

示例:监控数据查询

const { data } = await sorftimeClient.post('/forward', {
  path: '/api/MonitorQuery',
  body: {
    domain: 'amazon.com',
    asin: 'B0EXAMPLE1'
  }
});

示例:带云函数后处理

const { data } = await sorftimeClient.post('/forward', {
  path: '/api/ProductQuery',
  body: { domain: 'amazon.com', keyword: 'earbuds' },
  functionId: 'cloudFuncId123'
});

Angular HttpClient 调用示例:

this.http.post('https://server-msq.fmode.cn/api/sorftime/forward', {
  path: '/api/ProductQuery',
  body: { domain: 'amazon.com', keyword: 'earbuds' }
}).subscribe(res => {
  console.log(res);
});

5. TikHub API

TikHub 的 API Key 已在后端配置,前端无需传入认证信息。

5.1 健康检查

GET /api/tikhub/health

const res = await fetch('https://server-msq.fmode.cn/api/tikhub/health');
const data = await res.json();
// { "service": "tikhub", "timestamp": "2025-01-01T12:00:00.000Z" }

5.2 通用转发 (Forward)

通用转发接口可以调用任意 TikHub API 端点。支持 functionId 参数触发 Parse 云函数做后处理。

POST /api/tikhub/forward

请求参数:

参数 类型 必填 说明
path string TikHub API 路径,如 /api/v1/tiktok/web/fetch_user_profile
method string HTTP 方法,默认 GET
query object 查询参数
body object 请求体
headers object 额外请求头
functionId string Parse 云函数 ID
// axios
const { data } = await tikhubClient.post('/forward', {
  path: '/api/v1/tiktok/web/fetch_user_profile',
  method: 'GET',
  query: { unique_id: 'example_user' }
});

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/tikhub/forward', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    path: '/api/v1/tiktok/web/fetch_user_profile',
    method: 'GET',
    query: { unique_id: 'example_user' }
  })
});

5.3 用户相关接口 ⭐

GET /api/tikhub/tiktok/web/user-profile — 获取用户资料

参数 类型 必填 说明
unique_id string TikTok 用户名
// axios
const { data } = await tikhubClient.get('/tiktok/web/user-profile', {
  params: { unique_id: 'example_user' }
});

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/tikhub/tiktok/web/user-profile?unique_id=example_user');

GET /api/tikhub/tiktok/web/sec-user-id — 通过链接获取 sec_user_id

参数 类型 必填 说明
url string TikTok 用户主页链接
const { data } = await tikhubClient.get('/tiktok/web/sec-user-id', {
  params: { url: 'https://www.tiktok.com/@example_user' }
});

GET /api/tikhub/tiktok/app/v3/user-followers — 获取用户粉丝列表

参数 类型 必填 说明
user_id string 用户 ID
offset number 偏移量
count number 每页数量
const { data } = await tikhubClient.get('/tiktok/app/v3/user-followers', {
  params: { user_id: '6789012345', offset: 0, count: 20 }
});

GET /api/tikhub/tiktok/app/v3/user-following — 获取用户关注列表

参数 类型 必填 说明
user_id string 用户 ID
offset number 偏移量
count number 每页数量
const { data } = await tikhubClient.get('/tiktok/app/v3/user-following', {
  params: { user_id: '6789012345', offset: 0, count: 20 }
});

5.4 视频相关接口 ⭐

GET /api/tikhub/tiktok/app/v3/video — 获取单个视频详情

参数 类型 必填 说明
aweme_id string 视频 ID
// axios
const { data } = await tikhubClient.get('/tiktok/app/v3/video', {
  params: { aweme_id: '7123456789012345678' }
});

// fetch
const res = await fetch('https://server-msq.fmode.cn/api/tikhub/tiktok/app/v3/video?aweme_id=7123456789012345678');

GET /api/tikhub/tiktok/app/v3/user-repost-videos — 获取用户转发视频

参数 类型 必填 说明
user_id string 用户 ID
offset number 偏移量
count number 每页数量
const { data } = await tikhubClient.get('/tiktok/app/v3/user-repost-videos', {
  params: { user_id: '6789012345', offset: 0, count: 20 }
});

GET /api/tikhub/tiktok/app/v3/video-comments — 获取视频评论

参数 类型 必填 说明
aweme_id string 视频 ID
cursor number 分页游标
count number 每页数量
const { data } = await tikhubClient.get('/tiktok/app/v3/video-comments', {
  params: { aweme_id: '7123456789012345678', cursor: 0, count: 20 }
});

5.5 数据分析接口

GET /api/tikhub/tiktok/analytics/video-metrics — 视频数据指标

参数 类型 必填 说明
video_id string 视频 ID
const { data } = await tikhubClient.get('/tiktok/analytics/video-metrics', {
  params: { video_id: '7123456789012345678' }
});

POST /api/tikhub/tiktok/creator/account-insights — 创作者账户洞察

const { data } = await tikhubClient.post('/tiktok/creator/account-insights', {
  // 请求体参数根据 TikHub API 文档填写
  start_date: '2025-01-01',
  end_date: '2025-01-31'
});

5.6 电商接口

GET /api/tikhub/tiktok/shop/product-detail — TikTok 商品详情

参数 类型 必填 说明
product_id string 商品 ID
const { data } = await tikhubClient.get('/tiktok/shop/product-detail', {
  params: { product_id: '1234567890' }
});

5.7 广告接口

GET /api/tikhub/tiktok/ads/ads-detail — 广告详情

参数 类型 必填 说明
ad_id string 广告 ID
const { data } = await tikhubClient.get('/tiktok/ads/ads-detail', {
  params: { ad_id: 'AD12345' }
});

6. 附录:常见错误码

HTTP 状态码 说明 处理建议
400 请求参数错误 检查必填参数是否缺失、参数格式是否正确
401 认证失败 Amazon 接口:检查 shop-objectId 是否正确;其他平台:联系后端检查 Token 配置
403 权限不足 检查店铺是否有对应 API 权限
404 资源不存在 检查请求路径和参数 ID 是否正确
429 请求频率超限 降低请求频率,建议添加请求节流/防抖
500 服务器内部错误 联系后端排查,可能是上游 API 异常
502 上游服务错误 第三方平台 API 返回异常,稍后重试
503 服务不可用 服务维护中,稍后重试