Skip to content

Latest commit

 

History

History
339 lines (264 loc) · 7.29 KB

File metadata and controls

339 lines (264 loc) · 7.29 KB
sidebar_position 4
title Toolkit Package 使用指南
description @fecommunity/reactpress-toolkit 使用指南 — TypeScript Headless API SDK,从 OpenAPI 自动生成,对接 ReactPress REST。
keywords
reactpress
toolkit
headless
api sdk
typescript
openapi

@fecommunity/reactpress-toolkit 使用指南

ReactPress Toolkit 是一个基于 TypeScript 的 API 客户端工具包,从 OpenAPI/Swagger 规范自动生成,用于与 ReactPress 后端服务交互。

概述

ReactPress Toolkit 是一个 API 客户端库,提供与 ReactPress 后端服务交互的强类型接口。它包括:

  • 自动生成的 API 客户端 - 适用于所有 ReactPress 模块
  • TypeScript 定义 - 适用于所有数据契约
  • 实用函数 - 适用于常见操作
  • HTTP 客户端 - 内置认证和错误处理
  • 自动重试机制 - 适用于失败的请求
  • 请求/响应拦截器 - 适用于日志记录

该工具包从 ReactPress 后端的 OpenAPI 规范自动生成,确保始终与最新的 API 变化同步。

安装

npm install @fecommunity/reactpress-toolkit

yarn add @fecommunity/reactpress-toolkit

pnpm add @fecommunity/reactpress-toolkit

快速开始

使用默认 API 实例

import { api } from '@fecommunity/reactpress-toolkit';

// 获取所有文章
const articles = await api.article.findAll();

// 根据 ID 获取特定文章
const article = await api.article.findById('article-id');

// 创建新文章
const newArticle = await api.article.create({
  title: '我的新文章',
  content: '文章内容...',
  // ... 其他属性
});

使用命名导出

import { api, types, utils } from '@fecommunity/reactpress-toolkit';

// 使用类型化数据
const article: types.IArticle = {
  id: '1',
  title: '示例文章',
  // ... 其他属性
};

// 使用实用函数
const formattedDate = utils.formatDate(new Date());

配置

您可以创建具有特定配置的自定义 API 实例:

import { http } from '@fecommunity/reactpress-toolkit';

const customApi = http.createApiInstance({
  baseURL: 'https://api.yourdomain.com',
  timeout: 10000,
  // ... 其他 axios 配置选项
});

// 使用自定义实例
const articles = await customApi.article.findAll();

企业级特性

自动重试机制

import { http } from '@fecommunity/reactpress-toolkit';

// 配置重试设置
const customApi = http.createApiInstance({
  baseURL: 'https://api.yourdomain.com',
  retry: {
    retries: 3,
    retryDelay: 1000,
    retryCondition: (error) => {
      return error.response?.status === 503 || error.code === 'ECONNABORTED';
    }
  }
});

请求/响应拦截器

import { http } from '@fecommunity/reactpress-toolkit';

const monitoredApi = http.createApiInstance({
  baseURL: 'https://api.yourdomain.com',
  interceptors: {
    request: (config) => {
      // 添加日志、指标等
      console.log(`请求: ${config.method?.toUpperCase()} ${config.url}`);
      return config;
    },
    response: (response) => {
      // 添加日志、指标等
      console.log(`响应: ${response.status} ${response.config.url}`);
      return response;
    }
  }
});

认证处理

import { http, api, utils } from '@fecommunity/reactpress-toolkit';

// 自动令牌刷新
const secureApi = http.createApiInstance({
  baseURL: 'https://api.yourdomain.com',
  auth: {
    tokenRefresh: async (refreshToken) => {
      const response = await api.auth.refresh({ refreshToken });
      return response.data.accessToken;
    }
  }
});

类型定义

所有数据模型都是强类型的,可通过 types 导出使用:

import { types } from '@fecommunity/reactpress-toolkit';

const user: types.IUser = {
  name: 'John Doe',
  email: 'john@example.com',
  // ... 其他属性
};

可用的类型定义包括:

  • types.IUser
  • types.IArticle
  • types.ICategory
  • types.ITag
  • types.IComment
  • types.IFile
  • types.ISetting
  • types.IPage
  • types.IKnowledge
  • types.IView
  • types.I_SMTP

实用函数

工具包包含有用的实用函数:

import { utils } from '@fecommunity/reactpress-toolkit';

// 日期格式化
const formattedDate = utils.formatDate(new Date(), 'YYYY-MM-DD');

// 深度克隆
const clonedObject = utils.deepClone(originalObject);

// 错误处理
if (utils.ApiError.isInstance(error)) {
  console.log(`API 错误: ${error.code} - ${error.message}`);
}

// 数据验证
const isValidEmail = utils.validateEmail('user@example.com');

// 字符串处理
const slug = utils.createSlug('我的文章标题');

集成示例

React 集成

import { useState, useEffect } from 'react';
import { api, types } from '@fecommunity/reactpress-toolkit';

const ArticleList = () => {
  const [articles, setArticles] = useState<types.IArticle[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchArticles = async () => {
      try {
        const response = await api.article.findAll();
        setArticles(response.data);
      } catch (error) {
        console.error('获取文章失败:', error);
      } finally {
        setLoading(false);
      }
    };

    fetchArticles();
  }, []);

  if (loading) return <div>加载中...</div>;
  
  return (
    <div>
      {articles.map(article => (
        <div key={article.id}>
          <h2>{article.title}</h2>
          <p>{article.content}</p>
        </div>
      ))}
    </div>
  );
};

Node.js 集成

import { api, types } from '@fecommunity/reactpress-toolkit';

async function syncArticles() {
  try {
    // 从 ReactPress 获取文章
    const response = await api.article.findAll({
      limit: 100,
      offset: 0
    });
    
    // 处理文章
    const articles: types.IArticle[] = response.data;
    
    // 与另一个系统同步
    for (const article of articles) {
      // 您的同步逻辑
      console.log(`已同步文章: ${article.title}`);
    }
  } catch (error) {
    console.error('同步失败:', error);
  }
}

syncArticles();

最佳实践

错误处理

import { api, utils } from '@fecommunity/reactpress-toolkit';

try {
  const articles = await api.article.findAll();
  // 处理文章
} catch (error) {
  if (utils.ApiError.isInstance(error)) {
    switch (error.code) {
      case 401:
        // 处理未授权访问
        redirectToLogin();
        break;
      case 403:
        // 处理禁止访问
        showPermissionError();
        break;
      case 500:
        // 处理服务器错误
        showServerError();
        break;
      default:
        // 处理其他 API 错误
        showGenericError(error.message);
    }
  } else {
    // 处理网络错误
    showNetworkError();
  }
}

分页

import { api, types } from '@fecommunity/reactpress-toolkit';

async function fetchAllArticles(): Promise<types.IArticle[]> {
  const allArticles: types.IArticle[] = [];
  let offset = 0;
  const limit = 50;
  
  while (true) {
    const response = await api.article.findAll({ limit, offset });
    allArticles.push(...response.data);
    
    if (response.data.length < limit) {
      // 没有更多文章可获取
      break;
    }
    
    offset += limit;
  }
  
  return allArticles;
}