主题
Edge Function 云端API降级部署指南
⚠️ 2026-06-15 起:Edge Function 真相源 + 部署已统一到 RB 仓库。
lookup-or-fetch-word源码现位于~/reading-browser/supabase/functions/,由 RB 维护并从 RB 部署到共享 Supabase 项目 (jdtbyteiwnciqnfppztz)。RVH 端不再持有源码、不再执行 deploy。🗑️ 2026-08-02:
google-books-proxy/gutenberg-proxy已由 RB 删除(线上 + 源码), RVH 侧对应的调用管道同日清理完毕。RVH 现在只调lookup-or-fetch-word一个 function, 且只在 sync backfill 缺词时逐词调用。详见~/reading-browser/docs/cross-end/18-rvh-edge-jwt-handoff.md。
- Dart 端按稳定 URL/函数名 invoke,部署不变、运行时零影响。
- 要改 function:去 RB 改 + 从 RB 部署,见
~/reading-browser/docs/plans/supabase-consolidation-plan.md。- 下文部署步骤仅作历史/原理参考,实际操作以 RB 为准。
📋 概述
本文档指导你部署 lookup-or-fetch-word Edge Function,实现自动词库扩充功能。
功能:
- 用户查询生僻词时,自动调用 Free Dictionary API
- 将查询结果保存到 Supabase vocabulary_items 表
- 后续用户查询同一单词时直接从数据库返回
- 词库自动增长,所有用户共享受益
🚀 快速部署(15分钟)
前提条件
- ✅ 已注册 Supabase 账号并创建项目
- ✅ 已创建 vocabulary_items 表
- ✅ 已安装 Supabase CLI
步骤 1: 安装 Supabase CLI
macOS
bash
brew install supabase/tap/supabase或使用 npm
bash
npm install -g supabase验证安装
bash
supabase --version
# 应输出:1.x.x 或更高版本步骤 2: 登录 Supabase
bash
supabase login浏览器会打开登录页面,使用你的 GitHub 账号登录。
步骤 3: 链接到项目
3.1 获取项目 Reference ID
在 Supabase Dashboard:
- 进入你的项目
- Settings → General → Reference ID
- 复制 Reference ID(例如:
abcdefghijklmnop)
3.2 链接项目
bash
cd rvh # 2026-08-28 合仓:从仓根进本子目录(此前是 ~/reading_vocab_helper)
supabase link --project-ref YOUR_PROJECT_REF
# 将 YOUR_PROJECT_REF 替换为你的实际 Reference ID如果提示输入密码,输入你创建项目时设置的数据库密码。
步骤 4: 部署 Edge Function
bash
cd rvh # 2026-08-28 合仓:从仓根进本子目录(此前是 ~/reading_vocab_helper)
supabase functions deploy lookup-or-fetch-word预期输出:
Deploying Function lookup-or-fetch-word (project ref: YOUR_PROJECT_REF)
✔ Function deployed successfully!
Function URL: https://YOUR_PROJECT_REF.supabase.co/functions/v1/lookup-or-fetch-word步骤 5: 验证部署
5.1 获取 ANON_KEY
在 Supabase Dashboard:
- Settings → API
- 复制 Project API keys → anon → public
5.2 测试调用
bash
curl -i --location --request POST \
'https://YOUR_PROJECT_REF.supabase.co/functions/v1/lookup-or-fetch-word' \
--header 'Authorization: Bearer YOUR_ANON_KEY' \
--header 'Content-Type: application/json' \
--data '{"word":"example"}'预期响应(如果数据库中已有该词):
json
{
"data": {
"id": "uuid",
"word": "example",
"ipa_pronunciation": "/ɪɡˈzɑːmpəl/",
"definition": "a thing characteristic of its kind...",
...
},
"source": "database",
"cached": true
}或者(如果需要从API获取):
json
{
"data": {
"word": "obfuscate",
...
},
"source": "api",
"saved": true
}步骤 6: 查看日志
在 Supabase Dashboard:
- Edge Functions → lookup-or-fetch-word
- 点击 Logs 标签
- 查看调用日志、错误信息、执行时间
🧪 本地测试(可选)
1. 启动本地 Supabase
bash
cd rvh # 2026-08-28 合仓:从仓根进本子目录(此前是 ~/reading_vocab_helper)
supabase init # 首次需要初始化
supabase start2. 创建环境变量文件
bash
cat > supabase/.env.local <<EOF
SUPABASE_URL=http://localhost:54321
SUPABASE_SERVICE_ROLE_KEY=你的本地service_role_key
EOF本地 service_role_key 可以在 supabase start 输出中找到。
3. 本地运行 Edge Function
bash
supabase functions serve lookup-or-fetch-word --env-file supabase/.env.local4. 测试本地 Edge Function
bash
curl -i --location --request POST \
'http://localhost:54321/functions/v1/lookup-or-fetch-word' \
--header 'Authorization: Bearer YOUR_LOCAL_ANON_KEY' \
--header 'Content-Type: application/json' \
--data '{"word":"test"}'📱 客户端使用
部署完成后,客户端代码无需修改!
查询流程自动变为:
用户查询 "obfuscate"
↓
1. 本地缓存(未命中)
↓
2. 本地 vocabulary.db(未找到,生僻词)
↓
3. Supabase 表查询(未找到)
↓
4. 🆕 Edge Function 自动调用 API 并保存
↓
返回结果给用户
---
下次任何用户查询 "obfuscate"
↓
3. Supabase 表查询 ✅ 找到了!(上次已保存)🎯 验证完整流程
测试场景:查询超级生僻词
选择一个极生僻的单词(不在预装的 18,916 词中,库文件
lampio_dict.db)例如:"obfuscate", "perspicacious", "surreptitious"在应用中查询该单词
- 打开应用
- 拍照识别或手动输入
- 点击该单词
观察日志
第一次查询:
[UnifiedVocabulary] ℹ️ Cache miss: obfuscate, querying local first... [UnifiedVocabulary] 🔄 Querying local vocabulary.db: obfuscate (未找到) [UnifiedVocabulary] 🔄 Querying Supabase for rare word: obfuscate [Supabase] 🔍 Querying word: obfuscate [Supabase] 🔄 Word not in database, calling Edge Function for API fallback... [Supabase] ✅ Got word from Edge Function (source: api, saved: true) [UnifiedVocabulary] ✅ Supabase hit, cached: obfuscate第二次查询(或其他用户查询):
[UnifiedVocabulary] ℹ️ Cache miss: obfuscate, querying local first... [UnifiedVocabulary] 🔄 Querying local vocabulary.db: obfuscate (未找到) [UnifiedVocabulary] 🔄 Querying Supabase for rare word: obfuscate [Supabase] 🔍 Querying word: obfuscate [Supabase] ✅ Found word: obfuscate (from database) ← 直接从数据库返回!验证数据库
在 Supabase Dashboard → Table Editor → vocabulary_items:
- 搜索刚才查询的单词
- 应该能看到新增的记录
📊 监控和优化
查看调用统计
在 Supabase Dashboard → Edge Functions → lookup-or-fetch-word:
- Invocations:总调用次数
- Execution time:平均执行时间
- Errors:错误次数
- Logs:详细日志
预期性能
- 数据库命中:<50ms
- API 查询(首次):500ms - 2s
- 后续查询:<50ms(已缓存到数据库)
成本估算
Supabase 免费额度:
- Edge Function 调用:500,000 次/月
- 假设每天 100 个新词查询
- 每月消耗:约 3,000 次调用
- 完全在免费额度内 ✅
🔧 故障排查
问题 1:Edge Function 部署失败
症状:supabase functions deploy 报错
检查:
bash
# 验证项目链接
supabase projects list
# 重新链接
supabase link --project-ref YOUR_PROJECT_REF问题 2:Edge Function 调用返回 404
症状:客户端调用失败,返回 404
检查:
- 确认 Edge Function 已部署成功
- 检查函数名称是否正确(
lookup-or-fetch-word) - 验证 URL:
https://YOUR_PROJECT_REF.supabase.co/functions/v1/lookup-or-fetch-word
问题 3:Edge Function 调用超时
症状:查询生僻词时超时
原因:Free Dictionary API 响应慢或网络问题
解决:
- Edge Function 默认超时 10 秒,客户端超时 15 秒
- 如果经常超时,可以增加客户端超时时间
问题 4:单词保存失败
症状:Edge Function 返回 saved: false
检查 Supabase Dashboard 日志:
Settings → Logs → Edge Functions常见原因:
- vocabulary_items 表结构不匹配
- service_role_key 权限问题
- 数据库存储空间不足
问题 5:查询结果不包含音标或例句
原因:Free Dictionary API 数据质量问题(某些词没有完整数据)
预期行为:
- 正常情况,Edge Function 会尽量提取所有可用字段
- 如果 API 返回的数据不完整,某些字段可能为 null
🎉 完成
部署成功后:
- ✅ 用户查询生僻词会自动触发 API 查询
- ✅ 查询结果自动保存到 Supabase
- ✅ 后续所有用户查询该词时秒返回
- ✅ 词库自动增长,无需手动维护
- ✅ 完全在免费额度内
📚 相关文档
- Edge Function 代码说明:RB 仓库
~/reading-browser/supabase/functions/lookup-or-fetch-word/README.md(真相源已迁 RB) - Supabase Edge Functions 官方文档
- Free Dictionary API 文档
需要帮助? 查看 故障排查 章节或查阅 Supabase Dashboard 日志。