LeafWiki REST API 实测

LeafWiki v0.14.2 REST API 全链路 curl 实测:73 端点全景、Cookie+CSRF 双持认证、页面 CRUD 与乐观锁(PUT 全字段/DELETE 带 version)、树与检索标签、viewer/editor/admin 三角色权限边界、resync/快照/修订运维端点与 ZIP 导入。

LeafWikiLeafWiki文档管理WikiDocs2026/11/01

LeafWiki REST API 实测

基于 v0.14.2 实测(2026-11-01),目标实例为部署篇 Compose 栈(宿主端口 8141),示例账号 admin / q1w2e3r4。全部请求与响应为服务器上一手回显逐行照抄。官方标注「开发中」的 API Keys 不在本文范围(见《LeafWiki 配置参数详解》第五章)。

一、API 全景

LeafWiki 前后端同体,界面即本套 REST API 的消费者。从发布包内嵌前端产物枚举出全部端点(73 个),按域分组:

域端点
认证/api/auth/login、/login/totp、/logout、/me、/refresh-token、/password/forgot、/password/reset、/invite/accept
用户管理/api/users(GET/POST)、/api/users/{id}、/users/invite、/users/{id}/invite/resend、/users/me/password、/users/me/totp/*
页面/api/pages、/api/pages/{id}(GET/PUT/DELETE)、/move、/copy/{id}、/convert/{id}、/pin、/sort、/favorite、/links、/assets*、`/refactor/preview
定位/api/tree、/api/pages/by-path、/api/pages/lookup、/api/pages/ensure、/api/pages/slug-suggestion、/api/pages/permalink/{id}
检索与标签/api/search、/api/tags、/api/favorites、/api/links/broken
管理运维/api/admin/resync、`/api/admin/settings/public-access
导入/api/import/plan、/api/import/execute
杂项/api/config、/api/branding*、/api/user-settings、/api/user/avatar

二、认证模型:Cookie + CSRF 双持

登录(identifier 字段接受用户名或邮箱):

$ curl -s -c cookies.txt -X POST http://127.0.0.1:8141/api/auth/login \
    -H 'Content-Type: application/json' -d '{"identifier":"admin","password":"q1w2e3r4"}'
{"accessTokenExpiresAt":1793542984,"message":"Login successful","user":{"id":"H_sIThqDR","username":"admin","email":"admin@localhost","role":"admin","totpEnabled":false,"mustSetPassword":false}}

令牌经 HttpOnly Cookie 下发(access 默认 15m,refresh 168h,见 C1 篇),响应体只给过期时间戳;同时下发可读的 leafwiki_csrf Cookie。所有写操作必须回带 X-CSRF-Token 头(值取该 Cookie),实测缺失时:

{"error":"Invalid CSRF token"}

错误口令实测:

{"error":{"code":"auth_invalid_credentials","message":"Invalid credentials","template":"invalid credentials"}}

续期 POST /api/auth/refresh-token 实测 200;GET /api/auth/me 返回当前身份:

{"email":"admin@localhost","id":"H_sIThqDR","role":"admin","totpEnabled":false,"username":"admin"}

未认证访问业务端点实测 401:

$ curl -s http://127.0.0.1:8141/api/pages/RRpOT2qvR
{"error":"Missing or invalid access token"}

脚本化调用要点:curl -c/-b cookies.txt 维持会话,写操作前 CSRF=$(grep leafwiki_csrf cookies.txt | awk '{print $7}') 取令牌。

三、页面生命周期实测

3.1 建页

POST /api/pages,payload {title, slug, parentId, kind}(kind 取 page/section,parentId 用 root 或节点 ID):

$ curl -s -b cookies.txt -H "X-CSRF-Token: $CSRF" -H 'Content-Type: application/json' \
    -X POST http://127.0.0.1:8141/api/pages \
    -d '{"title":"Deploy Verify","slug":"deploy-verify","parentId":"root","kind":"page"}'
{"id":"RRpOT2qvR","title":"Deploy Verify","slug":"deploy-verify","version":"2026-11-01T14:08:51.712198164Z","position":1,"kind":"page","children":null,"metadata":{...},"content":"# Deploy Verify\n","path":"deploy-verify","tags":[],"properties":{}}

新页自动获得初始内容 # <title>,响应携带乐观锁 version。

3.2 编辑(全字段 PUT)

PUT /api/pages/{id} 要求全字段 {version,title,slug,content,tags,properties}——只传 {content,version} 实测被拒 page_invalid_request(排障实录见部署篇第六章)。成功响应返回新 version:

{"id":"RRpOT2qvR",...,"version":"2026-11-01T14:10:50.045641994Z",...}

tags 数组直接落盘为 Markdown 前置元数据(实测 data/root/deploy-verify.md 头部 tags: [s9, verify])。

乐观锁:携带过期 version 重试实测:

{"error":{"code":"page_version_conflict","message":"Page was changed by another request","template":"page was changed by another request"}}

正确姿势:先 GET /api/pages/{id} 取最新 version 再 PUT。

3.3 删除

DELETE /api/pages/{id} 必须带 version(查询参数),实测不带时:

{"error":{"code":"page_version_required","message":"Page version is required","template":"page version is required"}}

带 version 成功:

$ curl -s -b cookies.txt -H "X-CSRF-Token: $CSRF" -X DELETE 'http://127.0.0.1:8141/api/pages/vobRAh3vg?version=2026-11-01T14:20:58.217723517Z'
{"message":"Page deleted"}

删除后 GET /api/tree 复核该节点消失。

3.4 树与定位

GET /api/tree 返回全树(嵌套 children,节点含 id/title/slug/path/version/position/kind/metadata):

{"id":"root","title":"root","slug":"root","path":"","version":"...","kind":"section","children":[{"id":"89sSohqvR","title":"Welcome to LeafWiki","slug":"welcome-to-leafwiki",...}]}

按路径取页 GET /api/pages/by-path?path=deploy-verify 实测返回整页对象;/api/pages/lookup、/ensure、/slug-suggestion 为辅助端点;/api/pages/permalink/{id} 面向短链分享(实测以 slug 直访返回 404,正确用法为按页面 permalink ID 访问)。移动/排序/置顶分别走 /move、/sort({orderedIDs:[...]})、/pin({version,pinned})。

四、检索与标签

$ curl -s -b cookies.txt 'http://127.0.0.1:8141/api/search?q=callout'
{"limit":20,"offset":0,"count":1,"items":[{"page_id":"RRpOT2qvR","title":"Deploy Verify","path":"deploy-verify","kind":"page","rank":1,"excerpt":"Deploy Verify S9 实测页面:编辑功能验证。 [x] 建页 [x] 编辑 info LeafWiki <b>callout</b> 实测","tags":["s9","verify"]}],"tag_facets":[]}

要点(均实测):命中词 <b> 高亮内嵌于 title/excerpt;分页 limit/offset;tag_facets 支持标签分面过滤(配合 q 与标签参数);索引随编辑即时更新(编辑后立即可检索到新词)。GET /api/tags 返回全站标签计数:

[{"tag":"s9","count":1},{"tag":"verify","count":1}]

链接审计:GET /api/links/broken 实测 {"links":[]}(无断链)。

五、用户与角色权限实测

POST /api/users 建用户({username,email,password,role},role ∈ admin/editor/viewer):

{"id":"ClOhT23vR","username":"viewer01","email":"viewer01@localhost","role":"viewer","totpEnabled":false,"mustSetPassword":false}
{"id":"GtxR02qvR","username":"editor01","email":"editor01@localhost","role":"editor","totpEnabled":false,"mustSetPassword":false}

三角色边界实测:

操作viewer01editor01admin
GET /api/pages/{id} 读页✓ 200✓✓
POST /api/pages 建页403 {"error":"Editor or Admin role required"}✓ 成功建 editor-page✓
用户管理/运维端点——✓

GET /api/users(仅 admin)返回用户清单;/users/invite 走 SMTP 邀请(未配邮件时不可用);--editor-limit 可在服务层限制 admin+editor 总数。

六、运维端点实测

  • POST /api/admin/resync:外部修改磁盘 Markdown 后触发重同步,实测 {"ok":true},随后 API 读到外部追加段落;
  • GET /api/pages/{id}/revisions(需 --enable-revision):返回修订列表,含 id/type(content_update)/authorId/createdAt/contentHash/assetManifestHash 与 nextCursor 分页游标;配套 /revisions/latest、/revisions/compare?base=&target=、/revisions/{rid}/restore(POST);
  • GET /api/admin/snapshot 与 /snapshot/status:快照清单/状态,/snapshot/{name}/download 下载 ZIP;/api/admin/restore 在线恢复(写入 503 门禁,见 C1 篇第七章);
  • PUT /api/admin/settings/public-access:运行时切换匿名只读模式;
  • GET /api/config:运行态配置全量回显(见 C1 篇第十三章实测快照)。

七、批量导入 API

ZIP 导入两步式:POST /api/import/plan(上传计划,返回目标树与链接改写预览)→ POST /api/import/execute。编辑器/管理员角色可用,支持 Obsidian 风格 [[wiki 链接]] 改写;官方口径「适合结构较干净的目录,不是全格式自动转换器」。

八、小结

LeafWiki 的 REST API 完整覆盖页面 CRUD、树操作、检索、标签、用户角色、修订、快照与运维动作,认证采用 HttpOnly Cookie + X-CSRF-Token 双持,写操作全线乐观锁(version 必带,PUT 需全字段、DELETE 需 version 查询参数)。作为集成面:会话令牌 15m 默认时长适合脚本短任务,长周期自动化建议等待官方 API Keys 就绪或经反代认证头接入。三处实测坑位(PUT 全字段、DELETE 带 version、permalink 语义)已在正文标注,均为一手回显。

延伸阅读:《LeafWiki 二进制与 Compose 部署实战》(环境搭建与排障)、《LeafWiki 介绍与选型指南》(定位与对比)。

LeafWiki REST API 实测 - Quzuo