一句话文案哪里来?一言(简版)API 的真实业务接入笔记
在站点页脚、小程序欢迎语、命令行启动横幅这类非核心信息区,我们经常需要一句“有点温度”的文案。手写一批句子放数组里随机取值虽然简单,但内容量固定,用户多访问几次就容易看到重复;想把文案更新走一次发布流程又显得过重。随机句接口的价值,就是把这部分内容供给从业务代码中拆出去,由服务端维护语料,我们只负责调用和展示。
一言(简版)是 hitokoto 的精简版:纯文本随机一句,不带分类与出处,返回体更轻。它面向的正是这类装饰性场景,而不是需要聚合大量元数据的内容型业务。下面结合真实接入流程,把参数、鉴权、请求示例、返回字段和踩坑点逐一拆开讲。
适用场景与业务落点
站点页脚装饰文案
企业官网或个人博客的页脚通常有一行简短文案,用来增加人文气息。使用format=text时,接口直接返回纯文本,后端拿到字符串后原样拼进页面模板即可,不需要解析 JSON,也不涉及多层字段取值。
小程序欢迎语与首页提示
小程序启动页展示一句随机问候,可以提升首次进入的仪式感。移动端直接请求第三方接口存在两个问题:一是把 API Key 暴露在客户端,二是随机句内容不受自己控制。更稳妥的做法是由后端代理调用,将 text 格式的结果透传给小程序端。
命令行工具与 CI 输出点缀
在本地脚手架工具或 CI 构建日志的开头打印一句随机诗句,能缓解纯日志输出的枯燥感。此类调用频率低,对超时和重试的要求也不高,适合作为接口的早期验证场景。
接口能力边界
接入前先明确接口不做什么,能避免不少预期偏差:
- 只返回随机的一句话,不含分类、出处、作者等附加信息;
- 不提供指定句子、按关键词查询、按分类筛选等能力;
- 句子来源、语料扩充节奏和内容覆盖范围由服务端维护,客户端无感知;
- 文档标注 QPS 为 20/s,实际可用性以文档和线上表现为准。
一句话总结:这是一个“取即用”的轻接口,适合做装饰,不适合做内容核心。
参数与鉴权说明
Query 参数
接口仅暴露一个可选查询参数:
| 参数 | 是否必填 | 类型 | 取值 | 说明 |
|---|---|---|---|---|
format | 否 | string | json/text | 响应格式,默认json |
不传format时按 JSON 处理,返回结构化数据;显式指定format=text时直接返回纯文本句子。
鉴权方式
请求需携带请求头X-API-Key,值为调用方自身的 API Key。Key 的申请方式、权限范围和计费规则在官方文档中有说明,以文档为准。生产环境不要在前端代码里出现 Key,建议通过环境变量注入后端服务。
curl 请求示例
以下命令从环境变量读取 API Key,调用 JSON 格式接口:
curl -sS \ -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/yiyan?format=json"如果希望拿到纯文本,把 URL 末尾改为?format=text即可:
curl -sS \ -X GET \ -H "X-API-Key: $APIZERO_API_KEY" \ "https://v1.apizero.cn/api/yiyan?format=text"在本地调试时,可以先通过echo $APIZERO_API_KEY确认环境变量已配置。若未配置,需要先设置环境变量再执行上述命令。
代码接入示例
Python:按格式分流处理
import os import requests API_URL = "https://v1.apizero.cn/api/yiyan" API_KEY = os.environ["APIZERO_API_KEY"] def fetch_yiyan_json() -> str: """以 JSON 格式获取句子,返回 data.content 字段。""" resp = requests.get( API_URL, params={"format": "json"}, headers={"X-API-Key": API_KEY}, timeout=5, ) resp.raise_for_status() payload = resp.json() if payload.get("code") != 0: raise RuntimeError(payload.get("msg", "unknown error")) return payload["data"]["content"] def fetch_yiyan_text() -> str: """以 text 格式获取纯文本句子。""" resp = requests.get( API_URL, params={"format": "text"}, headers={"X-API-Key": API_KEY}, timeout=5, ) resp.raise_for_status() return resp.text两个函数分别应对两种业务形态:后端需要记录句子长度、池大小时用 JSON;直接透传给页面时用 text,连反序列化都省掉。
JavaScript(Node.js):封装为独立服务函数
const API_URL = "https://v1.apizero.cn/api/yiyan"; /** * 以 text 格式获取随机句子 * @returns {Promise<string>} */ export async function fetchYiyanText() { const resp = await fetch(`${API_URL}?format=text`, { headers: { "X-API-Key": process.env.APIZERO_API_KEY }, signal: AbortSignal.timeout(3000), }); if (!resp.ok) { throw new Error(`HTTP status: ${resp.status}`); } return resp.text(); }Node.js 18 及以上版本原生支持fetch和AbortSignal.timeout,无需额外安装依赖。调用方拿到字符串后,可以直接写入响应体或页面模板。
返回字段解读
JSON 格式
成功响应结构如下(示例数据):
{ "code": 0, "data": { "content": "落霞与孤鹜齐飞,秋水共长天一色。", "length": 16, "total_pool": 370 }, "msg": "成功" }| 字段 | 类型 | 说明 |
|---|---|---|
code | number | 业务状态码,0表示成功 |
msg | string | 状态描述,成功时为“成功” |
data.content | string | 随机句子正文 |
data.length | number | 当前句子的长度,示例中按中文单字计 |
data.total_pool | number | 当前句子池总量的参考值 |
需要特别说明:文档响应中的content、length、total_pool均为示例值,不代表每次调用的固定结果。尤其total_pool只是服务端当前池大小的一个参考快照,不要在业务逻辑中依赖它的具体数值。
text 格式
当format=text时,响应体是纯文本,例如:
落霞与孤鹜齐飞,秋水共长天一色。没有 JSON 结构,没有length与total_pool。客户端应该把整个响应体作为字符串处理,如果解析 JSON 会直接报错。
常见错误与排查途径
以下故障模式是基于 HTTP 语义和接口使用方式的常见排查思路,具体错误码定义以官方文档为准。
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 401 Unauthorized | 未携带X-API-Key,或 Key 无效 | 检查请求头是否完整、Key 是否复制准确 |
| 403 Forbidden | Key 无权限访问该接口 | 确认 Key 的接口权限范围 |
| 405 Method Not Allowed | 使用了 POST、PUT 等非 GET 方法 | 确认请求方法为 GET |
| 429 Too Many Requests | 请求频率超过文档标注的 QPS | 减少并发,加入退避重试 |
| 响应超时 | 网络波动或服务端异常 | 检查超时设置,观察服务可用性 |
调试时优先用上面给出的 curl 命令排除代码层干扰;curl 能通而代码不通,问题通常在参数拼接、请求头或代理设置上。
工程化注意事项
1. API Key 走环境变量,不进代码库
无论是 Python 的os.environ还是 Node.js 的process.env,都应该让 Key 从部署环境注入,而不是硬编码在源码中。代码仓库一旦泄露,密钥就可能被滥用。
2. 后端代理,前端不直连
浏览器或小程序端不应直接携带 Key 请求接口。正确做法是后端封装一个本地接口,内容再转发给前端,既保护密钥,也方便在代理层做缓存与降级。
3. 本地缓存与兜底文案
随机句服务属于“锦上添花”型依赖,不能因为它挂掉影响主流程。建议在内存中缓存上一次成功获取的句子,设置 30 分钟到数小时的过期时间;缓存过期且接口不可用时,退回内置的默认句,保证页面永不出现空白。
4. 超时控制必须显式设置
requests 和 fetch 默认都可能长时间挂起,生产环境务必传timeout(Python 5 秒、Node.js 3 秒是比较常见的起步值)。装饰性接口不值得占用工作线程等待过久。
5. 内容输出前做 HTML 转义
content字段是第三方文本,拼进 HTML 或小程序rich-text前要做转义或过滤,避免内容中的特殊字符破坏页面结构。如果是纯后端 Log 输出则无需处理。
结语
一言(简版)API 的价值不在功能复杂,而在“轻”。它把句子供给这件事外包出去,让开发者能少维护一批静态文案,同时也意味着我们要把它的能力边界看清楚:没有分类、没有出处、不支持筛选,QPS 也有明确约束。把这些边界写进技术方案,配合后端代理、缓存兜底和超时控制,它就能稳定服务于页脚、欢迎语这类真实业务场景。
参考文档
- 一言(简版)接口文档
- 接口原始文档
