Skip to content

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:

  1. 进入你的项目
  2. SettingsGeneralReference ID
  3. 复制 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:

  1. SettingsAPI
  2. 复制 Project API keysanonpublic

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:

  1. Edge Functionslookup-or-fetch-word
  2. 点击 Logs 标签
  3. 查看调用日志、错误信息、执行时间

🧪 本地测试(可选)

1. 启动本地 Supabase

bash
cd rvh   # 2026-08-28 合仓:从仓根进本子目录(此前是 ~/reading_vocab_helper)

supabase init  # 首次需要初始化
supabase start

2. 创建环境变量文件

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.local

4. 测试本地 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 表查询 ✅ 找到了!(上次已保存)

🎯 验证完整流程

测试场景:查询超级生僻词

  1. 选择一个极生僻的单词(不在预装的 18,916 词中,库文件 lampio_dict.db

    例如:"obfuscate", "perspicacious", "surreptitious"
  2. 在应用中查询该单词

    • 打开应用
    • 拍照识别或手动输入
    • 点击该单词
  3. 观察日志

    第一次查询

    [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)  ← 直接从数据库返回!
  4. 验证数据库

    在 Supabase Dashboard → Table Editorvocabulary_items

    • 搜索刚才查询的单词
    • 应该能看到新增的记录

📊 监控和优化

查看调用统计

在 Supabase Dashboard → Edge Functionslookup-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

检查

  1. 确认 Edge Function 已部署成功
  2. 检查函数名称是否正确(lookup-or-fetch-word
  3. 验证 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

🎉 完成

部署成功后:

  1. ✅ 用户查询生僻词会自动触发 API 查询
  2. ✅ 查询结果自动保存到 Supabase
  3. ✅ 后续所有用户查询该词时秒返回
  4. ✅ 词库自动增长,无需手动维护
  5. ✅ 完全在免费额度内

📚 相关文档


需要帮助? 查看 故障排查 章节或查阅 Supabase Dashboard 日志。