Outline API 完全开发指南:从基础集成到高级应用
概述
Outline 是一个基于 React 和 Node.js 打造的快速、协作式团队知识库。它可以让团队方便地存储和管理知识信息。本文档将详细介绍 Outline 的 RESTful API,帮助开发者从基础集成到高级应用,实现与 Outline 系统的无缝对接。
【基础指南】API 入门与环境配置
概念解析
Outline API 是一套基于 RESTful 设计原则的接口集合,允许开发者与 Outline 团队知识库进行交互。通过这些接口,可以实现文档的创建、查询、更新、删除等核心操作,为集成 Outline 到第三方系统或构建自定义工具提供了灵活的途径。
操作流程
- 环境准备
首先,确保你已经安装了必要的开发工具:
# 克隆项目仓库
git clone https://gitcode.com/GitHub_Trending/ou/outline
cd outline
# 安装依赖
yarn install
# 启动开发服务器
yarn dev
- 获取认证令牌
Outline API 使用 JWT (JSON Web Token) 进行认证。获取令牌的流程如下:
async function getAuthToken(email, password) {
try {
const response = await fetch('/api/auth.login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error(`认证失败: ${response.statusText}`);
}
const data = await response.json();
return data.data.token;
} catch (error) {
console.error('获取令牌失败:', error);
throw error;
}
}
- API 请求基础模板
以下是一个通用的 API 请求模板,可作为所有 API 调用的基础:
async function outlineApiRequest(endpoint, token, data = {}) {
try {
const response = await fetch(`/api/${endpoint}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify(data),
});
const responseData = await response.json();
if (!response.ok) {
throw new Error(responseData.error?.message || `API 请求失败: ${response.statusText}`);
}
return responseData;
} catch (error) {
console.error(`调用 ${endpoint} 失败:`, error);
throw error;
}
}
参数速查
| 参数名 | 类型 | 描述 |
|---|---|---|
| 基础URL | string | /api |
| 认证方式 | string | JWT (JSON Web Token) |
| 请求格式 | string | JSON |
| 响应格式 | string | JSON |
| 状态码 | number | 遵循HTTP标准状态码 |
调试技巧
- 使用 Postman 或 Insomnia 等 API 测试工具进行接口调试
- 开启 Outline 服务器的调试模式,获取详细的请求日志
- 使用浏览器的开发者工具监控网络请求,分析请求和响应数据
- 实现请求重试机制,处理网络不稳定情况
【核心功能】文档管理接口详解
概念解析
文档管理是 Outline API 最核心的功能,包括文档的创建、查询、更新和删除等操作。这些接口构成了与 Outline 知识库交互的基础。
操作流程
1. 获取文档列表
📝 功能场景:在企业内部系统中展示团队知识库的文档列表,支持按更新时间排序和按集合筛选。
async function getDocuments(token, filters = {}) {
return outlineApiRequest('documents.list', token, {
sort: 'updatedAt',
direction: 'DESC',
...filters
});
}
// 使用示例
const token = await getAuthToken('user@example.com', 'password');
const documents = await getDocuments(token, { collectionId: 'your-collection-id' });
console.log('文档列表:', documents.data);
参数说明:
| 参数名 | 类型 | 描述(默认值) |
|---|---|---|
| sort | string | 排序字段 (createdAt) |
| direction | string | 排序方向 (ASC) |
| userId | string | 创建者ID (null) |
| collectionId | string | 集合ID (null) |
| backlinkDocumentId | string | 反向链接文档ID (null) |
| parentDocumentId | string | 父文档ID (null) |
| template | boolean | 是否为模板文档 (false) |
| statusFilter | array | 状态筛选 (["published"]) |
常见问题:
- Q: 如何分页获取大量文档?
- A: 使用 pagination.offset 和 pagination.limit 参数控制分页,默认每页20条记录。
sequenceDiagram
participant Client
participant Server
Client->>Server: POST /api/documents.list
Server->>Server: 验证权限
Server->>Server: 应用筛选条件
Server->>Server: 查询数据库
Server->>Client: 返回文档列表和分页信息
2. 创建文档
📝 功能场景:在项目管理工具中,当创建新任务时自动在 Outline 中创建对应的文档,用于存储任务详情和相关资料。
async function createDocument(token, documentData) {
return outlineApiRequest('documents.create', token, documentData);
}
// 使用示例
const newDoc = await createDocument(token, {
title: '项目计划文档',
text: JSON.stringify({
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{ type: 'text', text: '这是使用API创建的项目计划文档' }
]
}
]
}),
collectionId: 'your-collection-id',
publish: true
});
console.log('新文档ID:', newDoc.data.id);
参数说明:
| 参数名 | 类型 | 描述(默认值) |
|---|---|---|
| id | string | 文档ID,可选 (自动生成) |
| title | string | 文档标题 (必填) |
| text | string | 文档内容,ProseMirror JSON格式 (必填) |
| icon | string | 文档图标 (file-text) |
| color | string | 图标颜色 (#000000) |
| publish | boolean | 是否发布 (false) |
| collectionId | string | 所属集合ID (必填) |
| parentDocumentId | string | 父文档ID (null) |
| templateId | string | 模板ID (null) |
| createdAt | string | 创建时间 (当前时间) |
| fullWidth | boolean | 是否全屏显示 (false) |
| template | boolean | 是否为模板文档 (false) |
常见问题:
- Q: 文档内容的格式有什么要求?
- A: 文档内容需要使用 ProseMirror JSON 格式,这是一种结构化的文档表示方式,支持富文本格式。
sequenceDiagram
participant Client
participant Server
Client->>Server: POST /api/documents.create
Server->>Server: 验证权限和参数
Server->>Server: 创建文档记录
Server->>Server: 生成文档ID
Server->>Server: 保存文档内容
Server->>Client: 返回新文档信息
3. 获取文档详情
📝 功能场景:在内部聊天工具中,当用户分享文档链接时,自动获取文档标题和摘要信息,显示在聊天窗口中。
async function getDocumentDetails(token, documentId) {
return outlineApiRequest('documents.info', token, { id: documentId });
}
// 使用示例
const docDetails = await getDocumentDetails(token, 'document-id');
console.log('文档标题:', docDetails.data.document.title);
console.log('文档内容:', docDetails.data.document.text);
参数说明:
| 参数名 | 类型 | 描述(默认值) |
|---|---|---|
| id | string | 文档ID (必填) |
| shareId | string | 共享链接ID (null) |
| apiVersion | number | API版本 (1) |
常见问题:
- Q: 如何获取文档的历史版本?
- A: 文档详情响应中的 revisions 字段包含了文档的历史版本信息,可以通过 revisionId 参数获取特定版本的内容。
4. 更新文档
📝 功能场景:当项目管理工具中的任务状态更新时,自动更新 Outline 中对应文档的状态信息,保持信息同步。
async function updateDocument(token, documentId, updates) {
return outlineApiRequest('documents.update', token, {
id: documentId,
...updates
});
}
// 使用示例
await updateDocument(token, 'document-id', {
title: '更新后的项目计划',
text: JSON.stringify({
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{ type: 'text', text: '这是更新后的文档内容' }
]
}
]
})
});
参数说明:
| 参数名 | 类型 | 描述(默认值) |
|---|---|---|
| id | string | 文档ID (必填) |
| title | string | 新文档标题 (当前标题) |
| text | string | 新文档内容 (当前内容) |
| icon | string | 文档图标 (当前图标) |
| color | string | 图标颜色 (当前颜色) |
| fullWidth | boolean | 是否全屏显示 (当前设置) |
| insightsEnabled | boolean | 是否启用洞察功能 (true) |
| publish | boolean | 是否发布 (当前状态) |
| templateId | string | 模板ID (当前模板) |
| collectionId | string | 所属集合ID (当前集合) |
| append | boolean | 是否追加内容 (false) |
| done | boolean | 编辑会话是否完成 (true) |
常见问题:
- Q: 如何部分更新文档内容而不是替换整个文档?
- A: 设置 append 参数为 true,可以将新内容追加到现有文档末尾,而不是完全替换。
5. 删除文档
📝 功能场景:在项目归档时,批量删除相关的临时文档,保持知识库整洁。
async function deleteDocument(token, documentId, permanent = false) {
return outlineApiRequest('documents.delete', token, {
id: documentId,
permanent
});
}
// 使用示例
await deleteDocument(token, 'document-id'); // 放入回收站
// await deleteDocument(token, 'document-id', true); // 永久删除
参数说明:
| 参数名 | 类型 | 描述(默认值) |
|---|---|---|
| id | string | 文档ID (必填) |
| permanent | boolean | 是否永久删除 (false) |
常见问题:
- Q: 永久删除和放入回收站有什么区别?
- A: 永久删除会直接从数据库中移除文档,无法恢复;而放入回收站的文档可以通过 restore 接口恢复。
接口版本差异
| 功能 | API v1 | API v2 |
|---|---|---|
| 文档内容格式 | 简化格式 | ProseMirror完整格式 |
| 响应结构 | 基础字段 | 包含更多元数据 |
| 权限信息 | 简单布尔值 | 详细权限对象 |
| 分页处理 | 简单offset/limit | 支持游标分页 |
调试技巧
- 使用
console.log输出完整的请求和响应数据,便于调试 - 对于文档内容,可以使用专门的 ProseMirror JSON 解析工具进行验证
- 实现乐观更新策略,先更新本地状态,再等待API响应
- 使用批量操作减少API调用次数,提高性能
【高级应用】文档状态与权限管理
概念解析
除了基本的文档CRUD操作,Outline API还提供了丰富的文档状态管理和权限控制功能,支持团队协作和内容治理。
操作流程
1. 文档状态管理
📝 功能场景:实现文档的生命周期管理,包括归档、恢复和发布状态控制。
// 归档文档
async function archiveDocument(token, documentId) {
return outlineApiRequest('documents.archive', token, { id: documentId });
}
// 恢复文档
async function restoreDocument(token, documentId, options = {}) {
return outlineApiRequest('documents.restore', token, {
id: documentId,
...options
});
}
// 取消发布
async function unpublishDocument(token, documentId, detach = false) {
return outlineApiRequest('documents.unpublish', token, {
id: documentId,
detach
});
}
// 使用示例
await archiveDocument(token, 'document-id');
await restoreDocument(token, 'document-id', { collectionId: 'new-collection-id' });
await unpublishDocument(token, 'document-id');
参数速查:
| 接口 | 参数 | 描述 |
|---|---|---|
| documents.archive | id | 文档ID |
| documents.restore | id, collectionId, revisionId | 文档ID,目标集合ID,恢复版本ID |
| documents.unpublish | id, detach | 文档ID,是否从集合分离 |
2. 文档权限管理
📝 功能场景:为不同团队成员设置不同的文档访问权限,确保敏感信息只对授权人员可见。
// 添加用户权限
async function addUserPermission(token, documentId, userId, permission) {
return outlineApiRequest('documents.add_user', token, {
id: documentId,
userId,
permission
});
}
// 移除用户权限
async function removeUserPermission(token, documentId, userId) {
return outlineApiRequest('documents.remove_user', token, {
id: documentId,
userId
});
}
// 添加组权限
async function addGroupPermission(token, documentId, groupId, permission) {
return outlineApiRequest('documents.add_group', token, {
id: documentId,
groupId,
permission
});
}
// 使用示例
await addUserPermission(token, 'document-id', 'user-id', 'read_write');
await addGroupPermission(token, 'document-id', 'group-id', 'read');
参数速查:
| 参数名 | 类型 | 描述 |
|---|---|---|
| id | string | 文档ID (必填) |
| userId | string | 用户ID (必填,用户权限接口) |
| groupId | string | 组ID (必填,组权限接口) |
| permission | string | 权限级别: read, read_write, admin (必填) |
权限级别说明:
- read: 只能查看文档
- read_write: 可以查看和编辑文档
- admin: 完全控制权,包括管理权限
classDiagram
class Document {
+string id
+string title
+string text
+enum status
+updateStatus()
+addPermission()
+removePermission()
}
class User {
+string id
+string name
}
class Group {
+string id
+string name
}
Document "1" -- "N" User : has permissions
Document "1" -- "N" Group : has permissions
接口关联关系
文档状态和权限管理接口通常与基础文档管理接口配合使用:
- 创建文档后设置初始权限
- 更新文档内容后调整发布状态
- 归档前检查用户权限
- 删除前验证管理员权限
调试技巧
- 使用权限检查工具,验证当前用户对文档的操作权限
- 实现权限变更日志,记录所有权限修改操作
- 使用批量权限管理接口,高效设置多个文档的权限
【实践案例】API集成最佳实践
文档搜索与过滤
📝 功能场景:实现企业内部知识库的全文搜索功能,支持按关键词、日期和状态筛选。
async function searchDocuments(token, query, options = {}) {
return outlineApiRequest('documents.search', token, {
query,
...options
});
}
// 使用示例
const results = await searchDocuments(token, '项目计划', {
collectionId: 'your-collection-id',
dateFilter: 'month',
statusFilter: ['published']
});
console.log(`找到 ${results.pagination.total} 个匹配结果`);
results.data.forEach(doc => {
console.log(`${doc.title} - ${doc.updatedAt}`);
});
文档导入导出
📝 功能场景:实现与其他文档系统的集成,支持批量导入导出文档。
// 导出文档
async function exportDocument(token, documentId, format = 'text/markdown') {
try {
const response = await fetch(`/api/documents.export`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
'Accept': format
},
body: JSON.stringify({ id: documentId })
});
if (!response.ok) {
throw new Error(`导出失败: ${response.statusText}`);
}
return await response.text();
} catch (error) {
console.error('文档导出失败:', error);
throw error;
}
}
// 导入文档
async function importDocument(token, file, options = {}) {
const formData = new FormData();
formData.append('file', file);
// 添加选项参数
Object.entries(options).forEach(([key, value]) => {
formData.append(key, value);
});
try {
const response = await fetch(`/api/documents.import`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});
if (!response.ok) {
throw new Error(`导入失败: ${response.statusText}`);
}
return await response.json();
} catch (error) {
console.error('文档导入失败:', error);
throw error;
}
}
// 使用示例
const markdownContent = await exportDocument(token, 'document-id');
console.log('导出的Markdown内容:', markdownContent);
// 导入示例 (浏览器环境)
// const fileInput = document.querySelector('input[type="file"]');
// const importResult = await importDocument(token, fileInput.files[0], {
// collectionId: 'target-collection-id',
// publish: true
// });
接口性能优化建议
-
批量操作:使用批量接口减少API调用次数,例如批量获取文档列表而非单个查询
-
合理缓存:对不常变化的数据进行缓存,减少重复请求
// 简单的缓存实现
const documentCache = new Map();
async function getDocumentWithCache(token, documentId) {
if (documentCache.has(documentId)) {
return documentCache.get(documentId);
}
const doc = await getDocumentDetails(token, documentId);
documentCache.set(documentId, doc);
// 设置过期时间 (5分钟)
setTimeout(() => {
documentCache.delete(documentId);
}, 5 * 60 * 1000);
return doc;
}
-
分页加载:实现无限滚动或分页加载,避免一次性加载过多数据
-
字段过滤:只请求需要的字段,减少数据传输量
-
异步处理:对于耗时操作(如文档导入),使用异步处理并轮询结果
Postman/Insomnia 配置导入示例
以下是一个 Postman 集合配置示例,可导入到 Postman 中快速开始使用 Outline API:
{
"info": {
"name": "Outline API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "认证",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"email\": \"{{email}}\", \"password\": \"{{password}}\"}"
},
"url": {
"raw": "{{baseUrl}}/api/auth.login",
"host": ["{{baseUrl}}"],
"path": ["api", "auth.login"]
}
},
"event": [
{
"listen": "test",
"script": {
"exec": [
"var jsonData = pm.response.json();",
"pm.environment.set(\"token\", jsonData.data.token);"
],
"type": "text/javascript"
}
}
]
},
{
"name": "获取文档列表",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "Authorization",
"value": "Bearer {{token}}"
}
],
"body": {
"mode": "raw",
"raw": "{\"sort\": \"updatedAt\", \"direction\": \"DESC\"}"
},
"url": {
"raw": "{{baseUrl}}/api/documents.list",
"host": ["{{baseUrl}}"],
"path": ["api", "documents.list"]
}
}
}
],
"variable": [
{
"key": "baseUrl",
"value": "http://localhost:3000"
},
{
"key": "email",
"value": ""
},
{
"key": "password",
"value": ""
},
{
"key": "token",
"value": ""
}
]
}
总结
Outline API 提供了强大而灵活的接口,使开发者能够构建各种集成和扩展,满足团队协作和知识管理的需求。从基础的文档CRUD操作到高级的权限管理和搜索功能,Outline API 为构建自定义知识管理解决方案提供了全面的支持。
通过本文档介绍的最佳实践和示例代码,开发者可以快速上手并充分利用 Outline API 的强大功能,为团队打造更高效的知识管理体验。
官方文档:docs/ARCHITECTURE.md
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5-w4a8GLM-5-w4a8基于混合专家架构,专为复杂系统工程与长周期智能体任务设计。支持单/多节点部署,适配Atlas 800T A3,采用w4a8量化技术,结合vLLM推理优化,高效平衡性能与精度,助力智能应用开发Jinja00
jiuwenclawJiuwenClaw 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。Python0208- QQwen3.5-397B-A17BQwen3.5 实现了重大飞跃,整合了多模态学习、架构效率、强化学习规模以及全球可访问性等方面的突破性进展,旨在为开发者和企业赋予前所未有的能力与效率。Jinja00
AtomGit城市坐标计划AtomGit 城市坐标计划开启!让开源有坐标,让城市有星火。致力于与城市合伙人共同构建并长期运营一个健康、活跃的本地开发者生态。01
MarkFlowy一款 AI Markdown 编辑器TSX01