- 新增 DELETE /api/projects/:slug 接口,支持根据 slug 删除项目 - 删除操作会级联删除关联的外部链接和标签关系 - 新增 GET /api/projects/:slug 接口,支持查询项目详情 - 添加完整的 API 参考文档(docs/api-reference.md) - 修复 ProjectDetail 组件的 iframe 嵌入逻辑,添加可嵌入域名白名单 - 删除旧的数据摄入流程文档,由新 API 文档替代
16 KiB
16 KiB
API 接口文档
AI 项目导航站对外提供的 REST API 接口文档
目录
1. 概述
1.1 Base URL
生产环境: https://your-domain.com
开发环境: http://localhost:3000
1.2 响应格式
所有接口返回 JSON 格式数据:
// 成功响应
{
"success": true,
"data": { ... },
"message": "操作成功"
}
// 错误响应
{
"success": false,
"error": "错误类型",
"details": ["详细错误信息1", "详细错误信息2"]
}
1.3 通用请求头
Content-Type: application/json
x-api-key: your-api-key-here # 需要认证的接口
2. 认证方式
API Key 认证
所有 API 接口均使用 API Key 进行认证。API Key 通过请求头 x-api-key 传递。
# 设置环境变量
WEBHOOK_API_KEY=your-secret-api-key
# 请求示例
curl -X POST https://your-domain.com/api/webhook/projects \
-H "Content-Type: application/json" \
-H "x-api-key: your-secret-api-key" \
-d '...'
注意事项:
- API Key 需要在服务端环境变量中配置
WEBHOOK_API_KEY - 请妥善保管 API Key,不要在客户端代码中暴露
- 建议定期轮换 API Key
3. 接口列表
3.1 创建/更新项目 (Webhook)
批量创建或更新项目数据。支持多级去重策略自动识别已存在的项目。
3.1.1 接口信息
POST /api/webhook/projects
3.1.2 请求参数
Headers:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x-api-key | string | 是 | API 密钥 |
| Content-Type | string | 是 | 必须为 application/json |
Body:
{
apiKey: string; // API 密钥(与 header x-api-key 二选一)
projects: ProjectInput[]; // 项目数组(1-100个)
}
ProjectInput 类型:
{
// 基础信息(必填)
name: string; // 中文名称
nameEn?: string; // 英文名称(可选)
description: string; // 中文描述
descriptionEn?: string; // 英文描述(可选)
// 内容(可选)
content?: string; // 中文内容(Markdown 格式)
contentEn?: string; // 英文内容(Markdown 格式)
// 状态(可选)
status?: "ACTIVE" | "ARCHIVED"; // 默认: "ACTIVE"
source?: string; // 数据来源标识
// 关联(必填)
tags: Array<{ // 标签数组(1-10个)
name: string; // 标签名
nameEn?: string; // 英文标签名(可选)
}>;
links: Array<{ // 外部链接数组(1-10个)
type: "WEBSITE" | "GITHUB" | "HUGGINGFACE" | "PAPER";
url: string; // 链接 URL
title?: string; // 链接标题(可选)
}>;
}
3.1.3 多级去重策略
Webhook 会按以下优先级识别已存在的项目:
- GitHub URL 精确匹配(最准确)
- Website URL 精确匹配
- slug 匹配(兜底)
如果找到已存在的项目,将执行更新操作:
- 更新所有项目字段
- 替换所有标签(删除旧的,创建新的)
- 替换所有链接(删除旧的,创建新的)
3.1.4 请求示例
curl -X POST https://your-domain.com/api/webhook/projects \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key" \
-d '{
"apiKey": "your-api-key",
"projects": [
{
"name": "LangChain",
"nameEn": "LangChain",
"description": "开发由语言模型驱动的应用程序框架",
"descriptionEn": "Developing applications powered by language models",
"content": "# LangChain\n\nLangChain 是一个...",
"contentEn": "# LangChain\n\nLangChain is a...",
"status": "ACTIVE",
"source": "GITHUB",
"tags": [
{ "name": "LLM", "nameEn": "Large Language Model" },
{ "name": "Python", "nameEn": "Python" },
{ "name": "开发框架", "nameEn": "Development Framework" }
],
"links": [
{
"type": "GITHUB",
"url": "https://github.com/langchain-ai/langchain",
"title": "GitHub 仓库"
},
{
"type": "WEBSITE",
"url": "https://langchain.com",
"title": "官方网站"
}
]
}
]
}'
3.1.5 响应示例
成功响应 (200 OK):
{
"success": true,
"processed": 1,
"created": 0,
"updated": 1,
"failed": 0,
"errors": []
}
错误响应 (400 Bad Request):
{
"success": false,
"error": "Validation error",
"details": [
"tags: Field must contain at least 1 element",
"links: Field must contain at most 10 elements"
]
}
认证失败 (401 Unauthorized):
{
"success": false,
"error": "Unauthorized",
"details": ["Invalid or missing API Key"]
}
3.2 获取项目详情
根据项目的 slug 获取项目详细信息。
3.2.1 接口信息
GET /api/projects/:slug
3.2.2 路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slug | string | 是 | 项目的唯一标识符 |
3.2.3 请求示例
curl -X GET https://your-domain.com/api/projects/langchain \
-H "Content-Type: application/json"
3.2.4 响应示例
成功响应 (200 OK):
{
"success": true,
"data": {
"id": "clx1234567890",
"name": "LangChain",
"nameEn": "LangChain",
"slug": "langchain",
"description": "开发由语言模型驱动的应用程序框架",
"descriptionEn": "Developing applications powered by language models",
"content": "# LangChain\n\nLangChain 是一个...",
"contentEn": "# LangChain\n\nLangChain is a...",
"status": "ACTIVE",
"source": "GITHUB",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-15T00:00:00.000Z",
"links": [
{
"id": "link123",
"type": "GITHUB",
"url": "https://github.com/langchain-ai/langchain",
"title": "GitHub 仓库"
}
],
"tags": [
{
"id": "tag123",
"name": "LLM",
"nameEn": "Large Language Model",
"slug": "large-language-model"
}
]
}
}
项目不存在 (404 Not Found):
{
"success": false,
"error": "Not Found",
"details": ["Project with slug \"nonexistent\" not found"]
}
3.3 删除项目
根据项目的 slug 删除项目及其所有关联数据。
3.3.1 接口信息
DELETE /api/projects/:slug
3.3.2 路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| slug | string | 是 | 项目的唯一标识符 |
3.3.3 请求头
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| x-api-key | string | 是 | API 密钥 |
| Content-Type | string | 是 | 必须为 application/json |
3.3.4 级联删除说明
由于数据库配置了 onDelete: Cascade,删除项目时会自动删除:
- ✅ 该项目的所有外部链接(
ExternalLink) - ✅ 该项目的所有标签关联(
ProjectTag) - ❌ Tag 本身不会被删除(只删除项目与标签的关联关系)
3.3.5 请求示例
curl -X DELETE https://your-domain.com/api/projects/langchain \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key"
3.3.6 响应示例
成功响应 (200 OK):
{
"success": true,
"message": "Project deleted successfully",
"data": {
"project": {
"id": "clx1234567890",
"name": "LangChain",
"nameEn": "LangChain",
"slug": "langchain"
},
"deleted": {
"linksCount": 2,
"tagsCount": 3
}
}
}
项目不存在 (404 Not Found):
{
"success": false,
"error": "Not Found",
"details": ["Project with slug \"nonexistent\" not found"]
}
认证失败 (401 Unauthorized):
{
"success": false,
"error": "Unauthorized",
"details": ["Invalid or missing API Key"]
}
4. 数据模型
4.1 Project 状态枚举
enum ProjectStatus {
ACTIVE = "ACTIVE", // 活跃项目
ARCHIVED = "ARCHIVED" // 已归档项目
}
4.2 链接类型枚举
enum LinkType {
WEBSITE = "WEBSITE", // 官方网站
GITHUB = "GITHUB", // GitHub 仓库
HUGGINGFACE = "HUGGINGFACE", // Hugging Face 模型/数据集
PAPER = "PAPER" // 论文链接
}
4.3 完整项目模型
interface Project {
id: string; // 项目唯一 ID(cuid 格式)
name: string; // 中文名称
nameEn: string | null; // 英文名称
slug: string; // URL 友好标识符(唯一)
description: string; // 中文描述
descriptionEn: string | null;// 英文描述
content: string | null; // 中文内容(Markdown)
contentEn: string | null; // 英文内容(Markdown)
status: ProjectStatus; // 项目状态
source: string | null; // 数据来源
createdAt: Date; // 创建时间
updatedAt: Date; // 更新时间
// 关联数据
tags: Tag[]; // 标签数组
links: ExternalLink[]; // 外部链接数组
}
4.4 Tag 模型
interface Tag {
id: string; // 标签唯一 ID
name: string; // 中文名称(唯一)
nameEn: string | null; // 英文名称
slug: string; // URL 友好标识符(唯一)
createdAt: Date; // 创建时间
}
4.5 ExternalLink 模型
interface ExternalLink {
id: string; // 链接唯一 ID
type: LinkType; // 链接类型
url: string; // 链接 URL
title: string | null; // 链接标题
projectId: string; // 所属项目 ID
}
5. 错误码
5.1 HTTP 状态码
| 状态码 | 说明 | 示例场景 |
|---|---|---|
| 200 OK | 请求成功 | 成功获取/创建/更新/删除数据 |
| 400 Bad Request | 请求参数错误 | 必填字段缺失、字段格式错误 |
| 401 Unauthorized | 认证失败 | API Key 无效或缺失 |
| 404 Not Found | 资源不存在 | 请求的项目 slug 不存在 |
| 500 Internal Server Error | 服务器内部错误 | 数据库连接失败、程序异常 |
5.2 业务错误类型
| 错误类型 | 说明 | 处理建议 |
|---|---|---|
| Validation error | 数据验证失败 | 检查请求体字段是否符合要求 |
| Unauthorized | API Key 无效 | 检查 API Key 是否正确 |
| Not Found | 资源不存在 | 确认 slug 是否正确 |
| Internal server error | 服务器错误 | 联系技术支持或稍后重试 |
5.3 验证规则
项目数据验证
// 必填字段
- name: 非空字符串,长度 1-200
- description: 非空字符串,长度 1-5000
- tags: 数组,长度 1-10,每个 tag.name 非空
- links: 数组,长度 1-10,每个 link.url 和 link.type 非空
// 可选字段
- nameEn: 字符串,长度 1-200
- descriptionEn: 字符串,长度 1-5000
- content/contentEn: 文本类型,支持 Markdown
- status: 枚举值 "ACTIVE" 或 "ARCHIVED",默认 "ACTIVE"
- source: 字符串,标识数据来源
// URL 格式
- links[*].url: 必须是有效的 HTTP/HTTPS URL
- links[*].type: 必须是 LinkType 枚举值之一
Webhook 批量操作限制
// 批量操作
- projects: 数组,长度 1-100
- apiKey: 必须与环境变量 WEBHOOK_API_KEY 匹配
6. 使用示例
6.1 完整的工作流示例
// 1. 创建/更新项目
const createResponse = await fetch('https://your-domain.com/api/webhook/projects', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'your-api-key'
},
body: JSON.stringify({
apiKey: 'your-api-key',
projects: [{
name: 'My AI Project',
nameEn: 'My AI Project',
description: '一个创新的 AI 项目',
descriptionEn: 'An innovative AI project',
status: 'ACTIVE',
source: 'MANUAL',
tags: [
{ name: 'AI', nameEn: 'Artificial Intelligence' },
{ name: '机器学习', nameEn: 'Machine Learning' }
],
links: [
{ type: 'GITHUB', url: 'https://github.com/user/project', title: 'GitHub' },
{ type: 'WEBSITE', url: 'https://project.com', title: 'Website' }
]
}]
})
});
const createResult = await createResponse.json();
console.log('创建结果:', createResult);
// { success: true, processed: 1, created: 1, updated: 0, failed: 0, errors: [] }
// 2. 获取项目详情
const slug = 'my-ai-project'; // 根据 nameEn 自动生成
const getResponse = await fetch(`https://your-domain.com/api/projects/${slug}`);
const getResult = await getResponse.json();
console.log('项目详情:', getResult.data);
// 3. 删除项目
const deleteResponse = await fetch(`https://your-domain.com/api/projects/${slug}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'your-api-key'
}
});
const deleteResult = await deleteResponse.json();
console.log('删除结果:', deleteResult);
6.2 批量创建项目示例
const projects = [
{
name: '项目 A',
nameEn: 'Project A',
description: '项目 A 的描述',
descriptionEn: 'Description of Project A',
tags: [{ name: '分类1' }],
links: [{ type: 'GITHUB', url: 'https://github.com/user/a' }]
},
{
name: '项目 B',
nameEn: 'Project B',
description: '项目 B 的描述',
descriptionEn: 'Description of Project B',
tags: [{ name: '分类2' }],
links: [{ type: 'GITHUB', url: 'https://github.com/user/b' }]
}
];
const response = await fetch('https://your-domain.com/api/webhook/projects', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'your-api-key'
},
body: JSON.stringify({
apiKey: 'your-api-key',
projects: projects
})
});
const result = await response.json();
console.log('批量创建结果:', result);
// { success: true, processed: 2, created: 2, updated: 0, failed: 0, errors: [] }
7. 注意事项
7.1 Slug 生成规则
项目 slug 根据以下规则自动生成:
- 优先使用
nameEn(英文) - 如果
nameEn不存在,使用name(中文) - 转换为小写
- 空格替换为连字符
- - 移除特殊字符
示例:
nameEn: "LangChain"→slug: "langchain"name: "大语言模型"→slug: "大语言模型"(会进行拼音转换)
7.2 标签去重
- 标签的
name字段在数据库中是唯一的 - 如果创建已存在的标签,会自动复用现有标签
- 标签的
slug也是唯一的,会根据nameEn或name自动生成
7.3 链接去重
- 同一个项目不能有重复的 URL
- 通过
projectId+url的组合保证唯一性
7.4 更新策略
- Webhook 使用 替换策略 更新标签和链接
- 不是增量更新,而是完全替换
- 更新时会删除旧的标签/链接关联,创建新的
8. 附录
8.1 环境变量配置
# .env
WEBHOOK_API_KEY=your-secret-api-key-here
DATABASE_URL=postgresql://user:password@host:5432/dbname?sslmode=require
8.2 相关文档
文档版本: v1.0.0 最后更新: 2024-01-11 维护者: AI 项目导航站团队