API 参考文档 (API Reference)
本文档提供文章模块所有REST API的完整说明,包括请求参数、响应格式和错误处理。
📋 目录
用户端API (Art icleController)
基础路径: /api/v1/articles
权限: 公开(部分需要登录)
GET /api/v1/articles
说明: 分页查询文章列表
请求参数:
| 参数 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| page | Integer | 否 | 页码(从1开始) | 1 |
| size | Integer | 否 | 每页数量(默认10,最大100) | 20 |
| categoryId | Long | 否 | 分类ID筛选 | 1234567890123456789 |
| keyword | String | 否 | 关键词搜索(标题/摘要) | "Spring Boot" |
请求示例:
curl -X GET "http://localhost:8080/api/v1/articles?page=1&size=10&categoryId=1234567890123456789"
响应示例:
{
"code": 200,
"message": "操作成功",
"data": {
"records": [
{
"id": "1234567890123456789",
"title": "MySQL 9.4 向量搜索实战",
"summary": "深入探讨 MySQL 9.4 的 VECTOR 类型...",
"coverImage": "https://example.com/cover.jpg",
"authorId": "9876543210987654321",
"categoryId": "1111111111111111111",
"publishTime": "2024-01-15T10:30:00",
"isTop": 0
}
],
"total": 100,
"page": 1,
"size": 10,
"pages": 10
}
}
GET /api/v1/articles/{id}
说明: 查询文章详情(包含完整内容)
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| id | Long | 文章ID |
请求示例:
curl -X GET "http://localhost:8080/api/v1/articles/1234567890123456789"
响应示例:
{
"code": 200,
"message": "操作成功",
"data": {
"id": "1234567890123456789",
"title": "MySQL 9.4 向量搜索实战",
"content": "# 引言\n\nMySQL 9.4引入了VECTOR类型...",
"contentHtml": "<h1>引言</h1><p>MySQL 9.4引入了VECTOR类型...</p>",
"summary": "深入探讨 MySQL 9.4 的 VECTOR 类型",
"coverImage": "https://example.com/cover.jpg",
"authorId": "9876543210987654321",
"categoryId": "1111111111111111111",
"status": 1,
"isTop": 0,
"isFeatured": 1,
"isCommentDisabled": 0,
"publishTime": "2024-01-15T10:30:00",
"tocJson": "[{\"level\":1,\"title\":\"引言\"}]",
"createTime": "2024-01-10T08:00:00",
"updateTime": "2024-01-15T10:30:00"
}
}
GET /api/v1/articles/{id}/related
说明: 获取相关文章推荐(基于向量搜索)
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| id | Long | 文章ID |
查询参数:
| 参数 | 类型 | 必填 | 说明 | 默认值 |
|---|---|---|---|---|
| limit | Integer | 否 | 推荐数量 | 5 |
推荐策略:
- ✅ Level 1: 向量相似度搜索(COSINE_DISTANCE)
- ⬇️ Level 2: 同分类文章(categoryId相同)
- ⬇️ Level 3: 最新发布文章(保底)
请求示例:
curl -X GET "http://localhost:8080/api/v1/articles/1234567890123456789/related?limit=5"
响应示例:
{
"code": 200,
"message": "操作成功",
"data": [
{
"id": "2222222222222222222",
"title": "PostgreSQL vs MySQL 向量搜索对比",
"summary": "两大数据库向量搜索能力横评",
"coverImage": "https://example.com/cover2.jpg",
"publishTime": "2024-01-20T14:00:00"
},
{
"id": "3333333333333333333",
"title": "向量数据库性能优化指南",
"summary": "从索引到查询的全方位优化",
"coverImage": "https://example.com/cover3.jpg",
"publishTime": "2024-01-18T09:30:00"
}
]
}
COSINE_DISTANCE 说明:
- 值域:
[0, 2] 0= 完全相同1= 正交(无关)2= 完全相反- 查询按距离升序排列(越小越相似)
管理端API (ArticleAdminController)
基础路径: /api/v1/admin/articles
权限: 需要 ROLE_ADMIN 权限
请求头:
Authorization: Bearer YOUR_JWT_TOKEN
POST /api/v1/admin/articles
说明: 创建文章(默认草稿状态)
请求体:
{
"title": "文章标题",
"content": "# Markdown 内容\n\n正文...",
"summary": "文章摘要(可选,不填会自动提取)",
"coverImage": "https://example.com/cover.jpg",
"categoryId": "1111111111111111111",
"tagIds": ["2222222222222222222", "3333333333333333333"],
"isTop": 0,
"isFeatured": 1,
"isCommentDisabled": 0
}
字段说明:
| 字段 | 类型 | 必填 | 说明 | 默认值 |
|---|---|---|---|---|
| title | String | ✅ | 标题(1-200字符) | - |
| content | String | ✅ | Markdown内容 | - |
| summary | String | 否 | 摘要(最多500字符) | 自动提取 |
| coverImage | String | 否 | 封面图URL | null |
| categoryId | Long | 否 | 分类ID | null |
| tagIds | Long[] | 否 | 标签ID数组 | [] |
| isTop | Integer | 否 | 是否置顶 | 0 |
| isFeatured | Integer | 否 | 是否精选 | 0 |
| isCommentDisabled | Integer | 否 | 是否禁用评论 | 0 |
响应示例:
{
"code": 200,
"message": "创建成功",
"data": "1234567890123456789"
}
后台处理流程:
- ✅ 参数校验(title/content必填)
- ✅ XSS过滤 - 防止脚本注入
- ✅ Markdown解析 - 转换为HTML
- ✅ TOC生成 - 提取标题结构
- ✅ 摘要提取 - 自动生成(如未提供)
- ✅ 保存到数据库(status=0草稿)
PUT /api/v1/admin/articles/{id}
说明: 更新文章
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| id | Long | 文章ID |
请求体: 同创建接口
响应示例:
{
"code": 200,
"message": "更新成功",
"data": true
}
PUT /api/v1/admin/articles/{id}/publish
说明: 发布文章
前置条件: status = DRAFT (0)
状态变更: DRAFT → PUBLISHED
触发事件: ArticlePublishedEvent
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| id | Long | 文章ID |
请求示例:
curl -X PUT "http://localhost:8080/api/v1/admin/articles/1234567890123456789/publish" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
响应示例:
{
"code": 200,
"message": "发布成功",
"data": null
}
后台处理流程:
- ✅ 验证状态(必须是草稿)
- ✅ 更新状态为 PUBLISHED
- ✅ 设置发布时间
- ✅ 发布
ArticlePublishedEvent - ✅ 异步处理 (不阻塞响应):
- 清理缓存
- 初始化统计
- 生成向量 (Embedding)
- 发送通知
PUT /api/v1/admin/articles/{id}/archive
说明: 归档文章
前置条件: status = PUBLISHED (1)
状态变更: PUBLISHED → ARCHIVED
请求示例:
curl -X PUT "http://localhost:8080/api/v1/admin/articles/1234567890123456789/archive" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
响应示例:
{
"code": 200,
"message": "归档成功",
"data": null
}
PUT /api/v1/admin/articles/{id}/unarchive
说明: 恢复归档文章
前置条件: status = ARCHIVED (2)
状态变更: ARCHIVED → PUBLISHED
请求示例:
curl -X PUT "http://localhost:8080/api/v1/admin/articles/1234567890123456789/unarchive" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
响应示例:
{
"code": 200,
"message": "恢复成功",
"data": null
}
DELETE /api/v1/admin/articles/{id}
说明: 删除文章(逻辑删除)
前置条件: 任何状态都可删除
逻辑删除: is_deleted = 0 → 1 (软删除)
请求示例:
curl -X DELETE "http://localhost:8080/api/v1/admin/articles/1234567890123456789" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
响应示例:
{
"code": 200,
"message": "删除成功",
"data": true
}
通用响应格式
所有API遵循统一的响应格式:
{
"code": 200, // HTTP状态码
"message": "操作成功", // 提示信息
"data": { ... } // 业务数据
}
成功响应
| 状态码 | 说明 |
|---|---|
| 200 | 操作成功 |
| 201 | 创建成功 |
错误响应
| 状态码 | 说明 | 示例 |
|---|---|---|
| 400 | 参数错误 | title不能为空 |
| 401 | 未登录 | Token缺失或过期 |
| 403 | 权限不足 | 需要ADMIN角色 |
| 404 | 资源不存在 | 文章不存在 |
| 409 | 业务冲突 | 草稿不能归档 |
| 500 | 服务器错误 | 系统异常 |
错误响应示例:
{
"code": 400,
"message": "参数错误:title不能为空",
"data": null
}
错误码说明
通用错误码 (System)
| 错误码 | HTTP状态 | 说明 |
|---|---|---|
| PARAM_ERROR | 400 | 参数校验失败 |
| UNAUTHORIZED | 401 | 未登录或Token过期 |
| ACCESS_DENIED | 403 | 无权限访问 |
| NOT_FOUND | 404 | 资源不存在 |
| INVALID_OPERATION | 409 | 非法操作(如草稿归档) |
| SYSTEM_ERROR | 500 | 系统内部错误 |
业务错误码 (Article)
| 错误码 | 说明 | 示例场景 |
|---|---|---|
| ARTICLE_NOT_FOUND | 文章不存在 | 查询不存在的ID |
| ARTICLE_STATUS_INVALID | 文章状态不允许此操作 | 草稿不能归档 |
| ARTICLE_ALREADY_PUBLISHED | 文章已发布 | 重复发布 |
| ARTICLE_ALREADY_ARCHIVED | 文章已归档 | 重复归档 |
错误响应示例:
{
"code": 409,
"message": "业务冲突:草稿不能归档",
"data": null,
"errorCode": "ARTICLE_STATUS_INVALID"
}
🔒 权限说明
用户端 (公开)
- ✅
GET /api/v1/articles- 匿名可访问 - ✅
GET /api/v1/articles/{id}- 匿名可访问 - ✅
GET /api/v1/articles/{id}/related- 匿名可访问
管理端 (需要登录 + ADMIN角色)
- 🔐
POST /api/v1/admin/articles- 需要ROLE_ADMIN - 🔐
PUT /api/v1/admin/articles/{id}- 需要ROLE_ADMIN - 🔐
PUT /api/v1/admin/articles/{id}/publish- 需要ROLE_ADMIN - 🔐
PUT /api/v1/admin/articles/{id}/archive- 需要ROLE_ADMIN - 🔐
PUT /api/v1/admin/articles/{id}/unarchive- 需要ROLE_ADMIN - 🔐
DELETE /api/v1/admin/articles/{id}- 需要ROLE_ADMIN
Token获取: 参考 认证文档
📊 字段类型说明
ArticleStatus (文章状态)
| 值 | 枚举 | 说明 | 允许操作 |
|---|---|---|---|
| 0 | DRAFT | 草稿 | 发布、删除 |
| 1 | PUBLISHED | 已发布 | 归档、删除 |
| 2 | ARCHIVED | 已归档 | 恢复、删除 |
布尔字段
| 字段 | 类型 | 说明 | 值域 |
|---|---|---|---|
| isTop | Integer | 是否置顶 | 0=否 1=是 |
| isFeatured | Integer | 是否精选 | 0=否 1=是 |
| isCommentDisabled | Integer | 是否禁用评论 | 0=否 1=是 |
🎯 最佳实践
1. 文章发布流程(推荐)
# Step 1: 创建草稿
curl -X POST /api/v1/admin/articles \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "标题",
"content": "# 内容"
}'
# 响应: {"data": "1234567890123456789"}
# Step 2: 预览(可选)
curl -X GET /api/v1/articles/1234567890123456789
# Step 3: 发布
curl -X PUT /api/v1/admin/articles/1234567890123456789/publish \
-H "Authorization: Bearer $TOKEN"
# Step 4: 验证相关推荐
curl -X GET /api/v1/articles/1234567890123456789/related?limit=5
2. 避免重复请求
使用乐观锁:
// ArticleEntity 自动包含 version 字段
@Version
private Integer version; // 每次更新自动+1
// 并发更新时,version不匹配会抛出 OptimisticLockException
3. 性能优化建议
- ✅ 使用分页查询(避免一次加载所有文章)
- ✅ 缓存文章详情(Redis,TTL 30分钟)
- ✅ 缓存相关推荐(向量搜索较慢)
- ✅ 定时预热热门文章
🔗 相关文档
- 架构设计 - 了解设计模式
需要更多帮助? 访问 Swagger UI 在线测试API。