Content DB API (1.0.0)

Download OpenAPI specification:

Cloudflare Workers + D1 + Hono 实现的内容管理 REST API。

核心特性

  • 双模型: 单表 articles, 通过 article_type 区分
    • hot — 机器采集的热点 (GitHub Trending / HN / 36kr 等)
    • knowledge — 手动创建的知识文章 (SEO / AI / 中医 等垂直领域)
  • CRUD only: 不提供采集端点, 热点文章由采集器直接写 D1
  • FTS5 trigram: 中文友好全文搜索
  • 统一响应: { ok, data, error, meta }
  • 统一鉴权: X-API-Key Header (除 /health 外所有接口)

错误码

HTTP 含义
401 缺/错 X-API-Key
404 资源不存在
422 Zod 校验失败, error.detail.fieldErrors 详细字段错误
500 服务器异常

响应格式

// 成功
{ "ok": true, "data": {...}, "meta": {"page": 1, "page_size": 20, "total": 123} }
// 失败
{ "ok": false, "error": {"code": 422, "message": "Invalid body", "detail": {...}} }

System

系统端点 (健康检查等)

健康检查

免鉴权, 用于存活探测

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

Articles

文章 CRUD 端点。

  • 创建/更新/删除 只针对知识文章 (article_type='knowledge')
  • 热点文章由采集器直接写 D1, 不通过此 API
  • 列表可同时查两类, 用 type 参数过滤

文章列表

列表查询。强烈建议至少传 type=hottype=knowledge, 让查询走部分索引。 支持多条件组合, 分页默认 page=1, page_size=20, page_size 上限 100。

Authorizations:
ApiKeyAuth
query Parameters
type
string
Enum: "hot" "knowledge"

文章类型

status
string
Enum: "draft" "scheduled" "published" "archived"

状态

category_id
integer >= 1

分类 ID

source
string

数据源 (如 github_trending / hn / 36kr)

tag
string

标签 slug

featured
boolean

仅精选

pinned
boolean

仅置顶

lang
string
Enum: "zh" "en" "ja" "other"

原始内容语言

since
integer <int64> >= 0

仅返回 source_published_at >= since (Unix ms)

page
integer >= 1
Default: 1

页码

page_size
integer [ 1 .. 100 ]
Default: 20

每页条数 (上限 100)

sort
string
Default: "created_at"
Enum: "created_at" "updated_at" "published_at" "source_published_at" "source_score"

排序字段

order
string
Default: "desc"
Enum: "asc" "desc"

排序方向

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": [
    ],
  • "meta": {
    }
}

创建知识文章

创建知识文章 (article_type='knowledge')。 热点文章 (article_type='hot') 由采集器直接写 D1, 不通过此端点。 自动生成 uuid / slug / word_count / reading_time

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
title
required
string [ 1 .. 200 ] characters
subtitle
string <= 500 characters
content
required
string non-empty
content_format
string
Default: "markdown"
Enum: "markdown" "html" "plain"
excerpt
string <= 1000 characters
cover_image
string <uri>
category_id
integer >= 1
status
string
Default: "draft"
Enum: "draft" "scheduled" "published" "archived"
visibility
string
Default: "public"
Enum: "public" "members" "private" "password"
password
string [ 4 .. 100 ] characters
scheduled_at
integer

Unix ms, status=scheduled 时必填

meta_title
string <= 200 characters
meta_description
string <= 500 characters
meta_keywords
string <= 200 characters
canonical_url
string <uri>
og_image
string <uri>
locale
string
Default: "zh-CN"
is_featured
boolean
Default: false
is_pinned
boolean
Default: false
allow_comments
boolean
Default: true
tag_ids
Array of integers[ items >= 1 ]

关联的 tag ID 列表 (整体替换)

Responses

Request samples

Content type
application/json
{
  • "title": "2026 SEO 关键词研究方法论",
  • "content": "# 关键词研究\n系统化拆解 5 个步骤:\n1. 意图分析\n2. 词库扩展\n3. 难度评估\n4. SERP 分析\n5. 优先级排序\n",
  • "category_id": 1,
  • "tag_ids": [
    ],
  • "status": "published",
  • "is_featured": true
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

文章详情 (含标签)

Authorizations:
ApiKeyAuth
path Parameters
uuid
required
string <uuid>

文章 UUID

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

更新知识文章 (partial update)

所有字段可选。传 tag_ids整体替换关联 (先删后插, 不是增量)。

Authorizations:
ApiKeyAuth
path Parameters
uuid
required
string <uuid>

文章 UUID

Request Body schema: application/json
required
title
required
string [ 1 .. 200 ] characters
subtitle
string <= 500 characters
content
required
string non-empty
content_format
string
Default: "markdown"
Enum: "markdown" "html" "plain"
excerpt
string <= 1000 characters
cover_image
string <uri>
category_id
integer >= 1
status
string
Default: "draft"
Enum: "draft" "scheduled" "published" "archived"
visibility
string
Default: "public"
Enum: "public" "members" "private" "password"
password
string [ 4 .. 100 ] characters
scheduled_at
integer

Unix ms, status=scheduled 时必填

meta_title
string <= 200 characters
meta_description
string <= 500 characters
meta_keywords
string <= 200 characters
canonical_url
string <uri>
og_image
string <uri>
locale
string
Default: "zh-CN"
is_featured
boolean
Default: false
is_pinned
boolean
Default: false
allow_comments
boolean
Default: true
tag_ids
Array of integers[ items >= 1 ]

关联的 tag ID 列表 (整体替换)

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "subtitle": "string",
  • "content": "string",
  • "content_format": "markdown",
  • "excerpt": "string",
  • "cover_image": "http://example.com",
  • "category_id": 1,
  • "status": "draft",
  • "visibility": "public",
  • "password": "string",
  • "scheduled_at": 0,
  • "meta_title": "string",
  • "meta_description": "string",
  • "meta_keywords": "string",
  • "canonical_url": "http://example.com",
  • "og_image": "http://example.com",
  • "locale": "zh-CN",
  • "is_featured": false,
  • "is_pinned": false,
  • "allow_comments": true,
  • "tag_ids": [
    ]
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

删除文章 (物理删除)

物理删除, 级联删除 article_tags 关联。谨慎使用。

Authorizations:
ApiKeyAuth
path Parameters
uuid
required
string <uuid>

文章 UUID

Responses

Response samples

Content type
application/json
{
  • "ok": false,
  • "error": {
    }
}

阅读数 +1

高并发友好, 直接 UPDATE ... RETURNING view_count, 无读后写。 可被前端在用户停留 > N 秒时调用, 也可被 SSR/爬虫在每次渲染时调用。

Authorizations:
ApiKeyAuth
path Parameters
uuid
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

Hot

热点端点 (由采集器写入 D1)。

  • /timelinesource_published_at 倒序 (跨源/单源时间流)
  • /topsource_score 倒序 (跨源/单源榜单)

热点时间流

source_published_at (原始发布时间) 倒序。 跨源或单源时间线, 传 source 过滤单源, 传 since 取"今日"或"近 N 小时"。

Authorizations:
ApiKeyAuth
query Parameters
source
string

数据源 (如 github_trending / hn / 36kr)

lang
string
Enum: "zh" "en" "ja" "other"

原始内容语言

since
integer <int64> >= 0

仅返回 source_published_at >= since (Unix ms)

page
integer >= 1
Default: 1

页码

page_size
integer [ 1 .. 100 ]
Default: 20

每页条数 (上限 100)

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": [
    ],
  • "meta": {
    }
}

热点榜单

source_score 倒序 (无分数则按时间)。

Authorizations:
ApiKeyAuth
query Parameters
source
string

数据源 (如 github_trending / hn / 36kr)

lang
string
Enum: "zh" "en" "ja" "other"

原始内容语言

page
integer >= 1
Default: 1

页码

page_size
integer [ 1 .. 100 ]
Default: 20

每页条数 (上限 100)

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": [
    ],
  • "meta": {
    }
}

Categories

知识文章的垂直领域 CRUD

分类列表

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": [
    ]
}

创建分类

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string [ 1 .. 100 ] characters
slug
string <= 100 characters

缺省自动生成

parent_id
integer >= 1
description
string <= 500 characters
cover_image
string <uri>
sort_order
integer
Default: 0

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "slug": "string",
  • "parent_id": 1,
  • "description": "string",
  • "cover_image": "http://example.com",
  • "sort_order": 0
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

分类详情

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer >= 1

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

更新分类

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer >= 1
Request Body schema: application/json
required
name
required
string [ 1 .. 100 ] characters
slug
string <= 100 characters

缺省自动生成

parent_id
integer >= 1
description
string <= 500 characters
cover_image
string <uri>
sort_order
integer
Default: 0

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "slug": "string",
  • "parent_id": 1,
  • "description": "string",
  • "cover_image": "http://example.com",
  • "sort_order": 0
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

删除分类

删除后, 关联文章的 category_id 会被置为 NULL (ON DELETE SET NULL)。

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer >= 1

Responses

Response samples

Content type
application/json
{
  • "ok": false,
  • "error": {
    }
}

Tags

通用标签 CRUD (知识文章主题词 + 热点 topic)

标签列表

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": [
    ]
}

创建标签

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string [ 1 .. 50 ] characters
slug
string <= 50 characters
description
string <= 500 characters

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "slug": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

标签详情

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer >= 1

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

更新标签

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer >= 1
Request Body schema: application/json
required
name
required
string [ 1 .. 50 ] characters
slug
string <= 50 characters
description
string <= 500 characters

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "slug": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

删除标签

删除后级联删除 article_tags 关联。

Authorizations:
ApiKeyAuth
path Parameters
id
required
integer >= 1

Responses

Response samples

Content type
application/json
{
  • "ok": false,
  • "error": {
    }
}

Search

FTS5 trigram 全文搜索

FTS5 trigram 全文搜索

中文友好的 trigram 分词搜索。

查询语法:

  • 关键词 — 子串匹配
  • 关键* — 前缀匹配
  • 关键 OR 词 — OR 关系
  • "关键 词" — NEAR 邻近
Authorizations:
ApiKeyAuth
query Parameters
q
required
string [ 1 .. 200 ] characters
type
string
Enum: "hot" "knowledge"

文章类型

status
string
Enum: "draft" "scheduled" "published" "archived"

状态

page
integer >= 1
Default: 1

页码

page_size
integer [ 1 .. 100 ]
Default: 20

每页条数 (上限 100)

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": [
    ],
  • "meta": {
    }
}

Maintenance

维护端点 (建议用 Cloudflare Cron Trigger 调度)

重算 tag 的 article_count

重建所有 tag 的 article_count 字段。建议用 Cron 每天跑一次。

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}

重算 category 的 article_count

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": null
}

发布到时的 scheduled 文章

status='scheduled'scheduled_at <= now() 的文章改为 published。 建议用 Cloudflare Cron Trigger 每分钟跑一次。

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "ok": true,
  • "data": {
    }
}