feat(docs): integrate version2 curriculum and stage-3 updates
概要
- 将 version2 分支的课程结构重构、第三阶段章节新增、示例资源迁移、高级 RAG 文档与 Vercel 部署配置等整合为 main 上的一次汇总提交
内容导航与 README 调整
- 更新 README 的总体介绍文案,引入“第零阶段 + 第一到第三阶段”的完整学习路径描述
- 将原先的“三阶段实战路径”说明替换为新版分阶段描述,突出从小游戏到跨平台复杂应用的学习节奏
- 删除已过时的“第二次更新将在分支 version2 合并到主分支”的提示,改为直接以 main 为主线
- 统一 README 顶部标题和排版风格,保证中英文导航、徽章展示等视觉结构一致
课程结构与章节导航更新
- 调整 docs 目录下的学习阶段导航结构,使 README 中的导航表与各 stage 实际目录对齐
- 补全并创建 stage-3 相关章节入口文件,用于承载高级阶段的课程内容
- 新增或更新以下章节入口:
- 高级核心技能:
- docs/stage-3/core-skills/3.1-mcp-claudecode-skills/index.md
- docs/stage-3/core-skills/3.2-long-running-tasks/index.md
- 多平台开发:
- docs/stage-3/cross-platform/3.3-wechat-miniprogram/index.md
- docs/stage-3/cross-platform/3.4-wechat-miniprogram-backend/index.md
- docs/stage-3/cross-platform/3.5-android-app/index.md
- docs/stage-3/cross-platform/3.6-ios-app/index.md
- 个人品牌:
- docs/stage-3/personal-brand/3.7-personal-website-blog/index.md
- 保持 stage-0、stage-1、stage-2 既有章节结构不变的前提下,对导航表格进行排版和链接校正,使整体课程地图清晰、可点击
示例与图片资源重组
- 将原先位于 docs/examples/example1/images/ 下的微信小程序示例图片,整体迁移到 stage-3 的正式课程路径中:
- 目标路径:docs/stage-3/3.3-how-to-build-a-wechat-miniprogram/example1/images/
- 通过 rename 方式保留 git 历史关系,避免图片资源被视为完全新增,从而方便后续追踪
- 为微信小程序示例新增 index 页面:
- docs/stage-3/3.3-how-to-build-a-wechat-miniprogram/example1/index.md
- 使该示例在“高级三:多平台开发:如何构建微信小程序”章节中有清晰的入口,对应实际实战内容
高级 RAG 与 AI 进阶文档
- 新增一篇系统介绍 RAG 的高级文档:
- docs/stage-3/ai-advanced/3.a1-rag-introduction/extra5-what-is-rag-and-how-does-it-work-and-future.md
- 覆盖内容包括:RAG 的基本概念、典型架构、工作流程以及未来演进方向,为第三阶段的复杂应用提供知识检索基础
- 配套引入多张插图,帮助读者从架构图和流程视角理解 RAG:
- docs/stage-3/ai-advanced/3.a1-rag-introduction/images/image1.png ~ image15.png
部署与工程配置
- 新增 vercel.json 配置文件,为项目在 Vercel 上的部署提供基础配置
- 明确文档构建产物的输出路径和静态站点托管方式
- 为之后的一键部署和自动化预览打下基础
依赖与锁文件更新
- 调整 package.json 中与新版文档结构和部署相关的配置,保持脚本和依赖与当前课程形态同步
- 更新 package-lock.json,以反映最新的依赖树和版本锁定状态
- 保证在执行 npm install / npm run build 时,依赖环境与 version2 中的实际使用情况一致
兼容性与行为说明
- 该提交通过 npm run build 验证,确保在整合 version2 内容后,VitePress 构建过程正常完成
- main 分支上的历史被压缩为一条有语义的“第二次大更新”提交,详细的开发过程仍保留在 version2 分支,用于后续需要时回溯
This commit is contained in:
@@ -21,8 +21,8 @@
|
||||
4. 学会 Supabse 进阶功能:realtime、storage、edge function
|
||||
5. 学会为Supabase增加 google 与 github 登录支持
|
||||
|
||||
* 一款支持用户注册 / 登录,并能将数据存入在线数据库的基础应用
|
||||
* 一套可复用的 Supabase 后端代码模板(数据库 + 用户管理等),供后续项目直接套用
|
||||
- 一款支持用户注册 / 登录,并能将数据存入在线数据库的基础应用
|
||||
- 一套可复用的 Supabase 后端代码模板(数据库 + 用户管理等),供后续项目直接套用
|
||||
|
||||
# 1. What is Database
|
||||
|
||||
@@ -103,11 +103,11 @@ user_info = {
|
||||
|
||||
归纳而言,数据库凭借高效的持久化存储、精细化管理与快速查询能力,主要解决了以下核心问题:
|
||||
|
||||
* **数据的持久化存储** : 如果没有数据库,数据将仅存在于应用的内存中,一旦应用关闭,数据就会丢失。数据库解决了这个问题,它将数据持久地存储在硬盘等存储介质上,确保了数据的长期保存,降低了丢失风险。
|
||||
* **便捷的数据查询与分析** : 数据库提供了强大的查询语言(如 SQL),让用户可以轻松、高效地对海量数据进行复杂的查询、筛选和分析,从而帮助企业做出更明智的决策。 如果没有数据库,从大量无序文件中查找特定信息将是一项极其耗时且困难的任务。
|
||||
* **支持高性能与高并发访问** : 数据库通过索引优化、查询缓存、连接池以及分布式架构等技术,能够在毫秒级时间内响应查询请求,并支撑成千上万用户的并发访问。这对于现代互联网应用(如电商平台秒杀活动、社交网络实时动态)至关重要,确保了系统的响应速度和用户体验。如果没有数据库的高性能支撑,面对海量用户请求时系统将会出现严重延迟甚至崩溃。
|
||||
* **保证数据的完整性和一致性** : 数据库通过一系列机制(如约束、触发器)来确保数据的准确性和一致性。 这意味着数据库中的数据必须符合预设的规则,例如,用户的年龄必须是数字,订单号必须是唯一的,从而有效防止了非法或无效数据的产生。
|
||||
* **确保数据的安全性** : 数据库提供了强大的安全机制,包括用户身份验证、访问控制和数据加密等,以保护数据免受未经授权的访问、修改或破坏。为了应对硬件故障、人为失误或恶意攻击等意外情况,数据库还提供了数据备份和恢复功能。 通过定期备份,可以在数据丢失或损坏时及时恢复,保障了业务的连续性。
|
||||
- **数据的持久化存储** : 如果没有数据库,数据将仅存在于应用的内存中,一旦应用关闭,数据就会丢失。数据库解决了这个问题,它将数据持久地存储在硬盘等存储介质上,确保了数据的长期保存,降低了丢失风险。
|
||||
- **便捷的数据查询与分析** : 数据库提供了强大的查询语言(如 SQL),让用户可以轻松、高效地对海量数据进行复杂的查询、筛选和分析,从而帮助企业做出更明智的决策。 如果没有数据库,从大量无序文件中查找特定信息将是一项极其耗时且困难的任务。
|
||||
- **支持高性能与高并发访问** : 数据库通过索引优化、查询缓存、连接池以及分布式架构等技术,能够在毫秒级时间内响应查询请求,并支撑成千上万用户的并发访问。这对于现代互联网应用(如电商平台秒杀活动、社交网络实时动态)至关重要,确保了系统的响应速度和用户体验。如果没有数据库的高性能支撑,面对海量用户请求时系统将会出现严重延迟甚至崩溃。
|
||||
- **保证数据的完整性和一致性** : 数据库通过一系列机制(如约束、触发器)来确保数据的准确性和一致性。 这意味着数据库中的数据必须符合预设的规则,例如,用户的年龄必须是数字,订单号必须是唯一的,从而有效防止了非法或无效数据的产生。
|
||||
- **确保数据的安全性** : 数据库提供了强大的安全机制,包括用户身份验证、访问控制和数据加密等,以保护数据免受未经授权的访问、修改或破坏。为了应对硬件故障、人为失误或恶意攻击等意外情况,数据库还提供了数据备份和恢复功能。 通过定期备份,可以在数据丢失或损坏时及时恢复,保障了业务的连续性。
|
||||
|
||||
## 1.3 Relational Database VS Non-Relational Database (NOSQL)
|
||||
|
||||
@@ -137,11 +137,11 @@ user_info = {
|
||||
|
||||
假设我们有一个博客平台,需要存储以下信息:
|
||||
|
||||
* 用户(Users):用户 ID、用户名、邮箱
|
||||
* 文章(Posts):文章 ID、标题、内容、作者 ID
|
||||
* 评论(Comments):评论 ID、评论内容、评论者 ID、所属文章 ID
|
||||
* 标签(Tags):标签 ID、标签名
|
||||
* 文章与标签的关系:单篇文章关联的多个标签、单个标签对应的多篇文章
|
||||
- 用户(Users):用户 ID、用户名、邮箱
|
||||
- 文章(Posts):文章 ID、标题、内容、作者 ID
|
||||
- 评论(Comments):评论 ID、评论内容、评论者 ID、所属文章 ID
|
||||
- 标签(Tags):标签 ID、标签名
|
||||
- 文章与标签的关系:单篇文章关联的多个标签、单个标签对应的多篇文章
|
||||
|
||||
### 关系数据库 (SQL) 示例
|
||||
|
||||
@@ -149,21 +149,21 @@ user_info = {
|
||||
|
||||
以 “内容平台的文章管理” 为例,我们不会把 “用户、文章、评论、标签” 混存,而是拆成 5 张功能单一的表,每张表都有明确的 “职责边界” 和严格的结构定义(Schema):
|
||||
|
||||
* `users` 表 (存储用户信息)
|
||||
- `users` 表 (存储用户信息)
|
||||
|
||||
| user_id (主键) | username | email |
|
||||
| -------------- | -------- | ----------------- |
|
||||
| 101 | Alice | alice@example.com |
|
||||
| 102 | Bob | bob@example.com |
|
||||
|
||||
* `posts` 表 (存储文章信息)
|
||||
- `posts` 表 (存储文章信息)
|
||||
|
||||
| post_id (主键) | title | content | author_id (外键) |
|
||||
| -------------- | --------- | ------------------------------ | ---------------- |
|
||||
| 1 | 初识SQL | 这是关于SQL数据库的一篇文章... | 101 |
|
||||
| 2 | NoSQL入门 | NoSQL提供了灵活的数据模型... | 102 |
|
||||
|
||||
* `comments` 表 (存储评论信息)
|
||||
- `comments` 表 (存储评论信息)
|
||||
|
||||
| comment_id (主键) | body | commenter_id (外键) | post_id (外键) |
|
||||
| ----------------- | ---------------- | ------------------- | -------------- |
|
||||
@@ -171,7 +171,7 @@ user_info = {
|
||||
| 1002 | 学习了。 | 101 | 2 |
|
||||
| 1003 | 有没有更多例子? | 101 | 1 |
|
||||
|
||||
* `tags` 表 (存储标签)
|
||||
- `tags` 表 (存储标签)
|
||||
|
||||
| tag_id (主键) | tag_name |
|
||||
| ------------- | -------- |
|
||||
@@ -179,7 +179,7 @@ user_info = {
|
||||
| 52 | 技术 |
|
||||
| 53 | 入门 |
|
||||
|
||||
* `post_tags` 表 (存储文章与标签的多对多关系,体现联表特点)
|
||||
- `post_tags` 表 (存储文章与标签的多对多关系,体现联表特点)
|
||||
|
||||
| post_id (外键) | tag_id (外键) |
|
||||
| -------------- | ------------- |
|
||||
@@ -275,9 +275,9 @@ Examples of NoSQL databases:
|
||||
|
||||
# 2. Supabase
|
||||
|
||||
在前面我们已经介绍了几类常见的数据库,以及它们各自适合的使用场景。不过在真实项目里,数据库通常只是后端体系中的一个基础模块:除了存储和查询数据,你还需要解决**用户注册登录、权限校验、文件上传与存储、对外 ****API**** 接口、甚至定时任务、实时通知**等一整套问题。仅仅选好数据库,并不能让你的应用“立刻就能上线运行”,中间还隔着一大圈繁琐的后端工程工作。
|
||||
在前面我们已经介绍了几类常见的数据库,以及它们各自适合的使用场景。不过在真实项目里,数据库通常只是后端体系中的一个基础模块:除了存储和查询数据,你还需要解决**用户注册登录、权限校验、文件上传与存储、对外 \*\***API\***\* 接口、甚至定时任务、实时通知**等一整套问题。仅仅选好数据库,并不能让你的应用“立刻就能上线运行”,中间还隔着一大圈繁琐的后端工程工作。
|
||||
|
||||
所以,我们需要考虑一个更大的背景: **后端服务** 。一个完整的应用,通常都由“前端 + 后端”组成:前端负责页面展示和用户交互,后端则负责数据存储、用户登录、业务逻辑处理等。过去,开发者往往需要自己搭建服务器、配置数据库、设计并实现 API,还要手动处理权限管理、安全策略、扩展性和监控运维等事务,整个过程既重复又耗时。为了解决这些重复劳动,业界出现了 **BaaS(Backend as a Service,后端即服务)** :把数据库、用户认证、文件存储、实时能力等常见后端功能打包成一个云端平台,开发者通过 SDK / API 就能直接调用这些能力,而无需从零搭建和运维基础设施。
|
||||
所以,我们需要考虑一个更大的背景: **后端服务** 。一个完整的应用,通常都由“前端 + 后端”组成:前端负责页面展示和用户交互,后端则负责数据存储、用户登录、业务逻辑处理等。过去,开发者往往需要自己搭建服务器、配置数据库、设计并实现 API,还要手动处理权限管理、安全策略、扩展性和监控运维等事务,整个过程既重复又耗时。为了解决这些重复劳动,业界出现了 **BaaS(Backend as a Service,后端即服务)** :把数据库、用户认证、文件存储、实时能力等常见后端功能打包成一个云端平台,开发者通过 SDK / API 就能直接调用这些能力,而无需从零搭建和运维基础设施。
|
||||
|
||||
在这个背景下,[Supabase](https://supabase.com/) 就可以看作是新一代的 BaaS 代表:它以 PostgreSQL 作为核心数据库,在其之上集成了 Auth、Storage、Realtime、Edge Functions、Vector 等一整套后端能力,为开发者提供一个“以 Postgres 为中心的一站式后端平台”。接下来,我们就从这个角度出发,从“只选数据库”升级到“选择完整的后端开发平台”,具体看看 Supabase 能帮我们省掉哪些工作,又是如何让一个项目从原型到可用产品的距离大幅缩短的。
|
||||
|
||||
@@ -307,8 +307,8 @@ Table Editor 可以当成是 Supabase 的可视化数据表编辑器,它能让
|
||||
|
||||
点击编辑器顶部的 Schema 下拉框可切换不同容器,日常开发中一般只需关注两类:
|
||||
|
||||
* `public`:默认的公共资源容器,开发者新建的业务表(如 “文章表”“评论表”)均存储于此;
|
||||
* `auth`:用户认证专属容器,其中的 `users` 表自动存储所有注册用户信息(如用户 ID、邮箱、登录时间),不建议手动修改此 Schema 下的默认表,避免影响认证功能;
|
||||
- `public`:默认的公共资源容器,开发者新建的业务表(如 “文章表”“评论表”)均存储于此;
|
||||
- `auth`:用户认证专属容器,其中的 `users` 表自动存储所有注册用户信息(如用户 ID、邮箱、登录时间),不建议手动修改此 Schema 下的默认表,避免影响认证功能;
|
||||
|
||||

|
||||
|
||||
@@ -368,7 +368,7 @@ Storage 是 Supabase 的存储系统,兼容 amazon cloud 的 s3 概念,可
|
||||
|
||||
> Amazon Cloud(亚马逊云服务,简称 AWS)是亚马逊提供的云计算平台(就像一个大型的网络机房,你可以按需租用计算和存储资源)。S3(Simple Storage Service)是 AWS 里专门用来存储文件的服务(类似一个无限大的网盘,可以存图片、视频、备份等各种文件),它是目前最流行的对象存储服务,已经成为了事实上的行业标准。
|
||||
>
|
||||
> **为什么要做成 S3 兼容 ****API** ** ?** :S3 已经存在近 20 年,市面上有大量现成的工具、SDK 和文档,兼容 S3 意味着你可以直接用这些资源,不用从头开始制作各类相关工具,能够快速满足业务上线的需求。
|
||||
> **为什么要做成 S3 兼容 \*\***API\*\* ** ?** :S3 已经存在近 20 年,市面上有大量现成的工具、SDK 和文档,兼容 S3 意味着你可以直接用这些资源,不用从头开始制作各类相关工具,能够快速满足业务上线的需求。
|
||||
|
||||
### Edge Functions
|
||||
|
||||
@@ -395,7 +395,7 @@ const supabaseKey = "Supabase anon_key";
|
||||
// 调用函数
|
||||
async function callEdgeFunction() {
|
||||
const url = `https://${projectId}.supabase.co/functions/v1/${functionName}`;
|
||||
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
@@ -451,13 +451,13 @@ Project Settings 是 Supabase 项目的高级配置部分,你可在此实现
|
||||
|
||||
其余配置项在当前阶段无需深究,待后续有进阶使用需求时再逐一探索即可。
|
||||
|
||||
## 2.1 Create Your First SQL Table
|
||||
## 2.1 Create Your First SQL Table
|
||||
|
||||
以上是 Supabase 的界面介绍,接下来我们将深入 Supabase 的核心数据库的操作环节。
|
||||
|
||||
在 Supabase 中创建数据表,主要有以下两种常用方式,你可以根据需求选择:
|
||||
|
||||
1. (推荐)借助大语言模型生成适配 Supabase 的 SQL 语句,直接在 **SQL Editor(** 前文介绍的 SQL 语句执行器)中粘贴执行,高效快捷,我们会在下个部分环节重点说明这个操作过程。
|
||||
1. (推荐)借助大语言模型生成适配 Supabase 的 SQL 语句,直接在 **SQL Editor(** 前文介绍的 SQL 语句执行器)中粘贴执行,高效快捷,我们会在下个部分环节重点说明这个操作过程。
|
||||
2. 通过可视化操作创建:在左侧侧边栏找到 Database 模块,点击进入后选中侧边栏的 Tables,在右侧点击 New table 按钮,即可通过图形化界面创建数据表。
|
||||
|
||||

|
||||
@@ -575,7 +575,7 @@ INSERT INTO orders (user_id, status, amount, details, placed_at, is_paid) VALUES
|
||||
-- |... | ... | ... | ... | ... | ... |
|
||||
```
|
||||
|
||||
执行成功后,此时表中已经插入了原始数据,你可以进入到 Table Editor 界面刷新后看到结果,也可以直接在 SQL Editor 界面中新建窗口,执行查询语句 `SELECT * FROM orders;`查看结果:
|
||||
执行成功后,此时表中已经插入了原始数据,你可以进入到 Table Editor 界面刷新后看到结果,也可以直接在 SQL Editor 界面中新建窗口,执行查询语句 `SELECT * FROM orders;`查看结果:
|
||||
|
||||

|
||||
|
||||
@@ -603,29 +603,29 @@ SELECT id, details -> 'items' AS item_list FROM orders;
|
||||
-- Expected Output: Each row shows id and an array from JSON with item details.
|
||||
```
|
||||
|
||||
* **示例 1:** 返回 `orders` 表中的所有行和列,与第二步的输出类似。
|
||||
* **示例 2:** 仅返回状态为 'pending' 的订单,且只包含指定的列:
|
||||
- **示例 1:** 返回 `orders` 表中的所有行和列,与第二步的输出类似。
|
||||
- **示例 2:** 仅返回状态为 'pending' 的订单,且只包含指定的列:
|
||||
|
||||

|
||||
|
||||
* **示例 3:** 仅返回已支付的订单,并显示指定的列:
|
||||
- **示例 3:** 仅返回已支付的订单,并显示指定的列:
|
||||
|
||||
| id | status | is_paid | amount |
|
||||
| -- | ------ | ------- | ------ |
|
||||
| 2 | paid | true | 50.00 |
|
||||
| 4 | paid | true | 22.98 |
|
||||
| 6 | paid | true | 8.00 |
|
||||
| 8 | paid | true | 26.99 |
|
||||
| 10 | paid | true | 19.89 |
|
||||
| id | status | is_paid | amount |
|
||||
| --- | ------ | ------- | ------ |
|
||||
| 2 | paid | true | 50.00 |
|
||||
| 4 | paid | true | 22.98 |
|
||||
| 6 | paid | true | 8.00 |
|
||||
| 8 | paid | true | 26.99 |
|
||||
| 10 | paid | true | 19.89 |
|
||||
|
||||
* **示例 4:** 返回每个订单的 `id` 和从 `details` 字段中提取的 `items` 数组:
|
||||
- **示例 4:** 返回每个订单的 `id` 和从 `details` 字段中提取的 `items` 数组:
|
||||
|
||||
| id | item_list |
|
||||
| --- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| id | item_list |
|
||||
| --- | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1 | `[{"qty":1,"sku":"BGR001","name":"Beef Burger","price":12}]` |
|
||||
| 2 | `[{"qty":2,"sku":"BGR002","name":"Chicken Burger","price":10},{"qty":2,"sku":"DRK001","name":"Lemonade","price":5}]` |
|
||||
| 3 | `[{"qty":3,"sku":"FRY001","name":"French Fries","price":5}]` |
|
||||
| ... | ... |
|
||||
| ... | ... |
|
||||
|
||||
### **2.3.4 **`INSERT`** - 插入单条记录**
|
||||
|
||||
@@ -704,7 +704,7 @@ RLS 正是为解决这类数据安全与隔离需求而生。它允许开发者
|
||||
|
||||
在 Supabase 中,RLS 与用户认证系统深度绑定,使用起来更为便捷。Supabase 提供了一个专用函数 `auth.uid()`,它能直接返回 “当前发起请求的已登录用户” 的唯一 ID(格式为 UUID)。借助这个函数,我们可以轻松编写策略,实现 “数据行与用户身份” 的精准关联(比如前文提到的 “订单 `user_id` 匹配当前用户 ID”)。
|
||||
|
||||
启用 RLS 策略的方式很灵活,你可以在 Supabase 数据库管理界面中的 “RLS” 按钮,直接配置并启用策略:
|
||||
启用 RLS 策略的方式很灵活,你可以在 Supabase 数据库管理界面中的 “RLS” 按钮,直接配置并启用策略:
|
||||
|
||||

|
||||
|
||||
@@ -835,10 +835,10 @@ const { error: err } = await supabaseClient.auth.signUp({
|
||||
email,
|
||||
password,
|
||||
options: {
|
||||
data: {
|
||||
full_name: fullName || null,
|
||||
birthday: birthday || null,
|
||||
avatar_url: avatarUrl || null
|
||||
data: {
|
||||
full_name: fullName || null,
|
||||
birthday: birthday || null,
|
||||
avatar_url: avatarUrl || null
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -867,6 +867,7 @@ const { error: err } = await supabaseClient.auth.signUp({
|
||||
1. 请先领取新手礼包,完成商品购买操作。
|
||||
2. 尝试找到用户权限的设定数据表位置,将权限修改为 `admin`,并成功在订单管理界面修改商品数量
|
||||
3. 尝试在数据表内定位到钱包金额相关表,通过修改使剩余钱包金额增加。
|
||||
|
||||
# 4. Build Your First Supabase App
|
||||
|
||||
经过前面的系统学习,你已掌握 Supabase 的核心能力(数据库操作、用户认证、RLS 安全策略),现在是时候亲自动手,搭建属于你的第一个包含数据库、支持用户登录系统的应用了!
|
||||
@@ -933,6 +934,7 @@ const { error: err } = await supabaseClient.auth.signUp({
|
||||
|
||||
1. 将用户管理系统集成到贪吃蛇游戏演示版中
|
||||
2. 将用户管理系统集成到你的应用程序中(如果之前已开发过一个应用程序)
|
||||
|
||||
# 3. Become Supabase Master
|
||||
|
||||
以上是 Supabase 的基本操作,接下来的旅程中我们将会接触 Supbase 的进阶原理和功能,你将理解为什么我们会选择 Supabase 作为教学案例,以及如何使用 Supbase 实现更高级的操作,协助你实现更复杂的交互功能,并且在学习这些功能后,即便面对 Supabase 之外的其他同类工具,你也能触类旁通,从更本质的层面理解后端服务的核心原理。当然,你并不需要在短时间内学会全部,也许只需要学会第三方登录支持已经足够,你可以先浏览下列内容,直到项目遇到对应的需求时再倒回来深入学习。
|
||||
@@ -999,16 +1001,16 @@ Supabase 将这些后端能力打包为开箱即用的服务(PostgreSQL数据
|
||||
|
||||
同样地,你也需要在 GitHub 上注册一个 OAuth 应用。
|
||||
|
||||
1. **进入 ****GitHub** ** Developer Settings** :
|
||||
|
||||
1. **进入 \*\***GitHub\*\* ** Developer Settings** :
|
||||
1. 登录你的 GitHub 账户。
|
||||
2. 点击右上角的头像,进入 “Settings”。
|
||||
3. 在左侧导航栏的底部,找到 “Developer settings”。
|
||||
|
||||
2. **注册新应用 (Register a new application)** :
|
||||
3. 选择 “OAuth Apps”,然后点击 “New OAuth App”。
|
||||
4. 填写应用名称,例如 “My Burger Shop”。
|
||||
5. **Homepage URL** : 填写你应用的线上地址,或者本地开发地址 `http://localhost:3000`。
|
||||
6. **Authorization ****callback** ** URL** : 填入你的 Supabase 项目的回调 URL。同样,你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “GitHub” 中找到它,格式为 `https://<你的项目ID>.supabase.co/auth/v1/callback`。
|
||||
6. **Authorization \*\***callback\*\* ** URL** : 填入你的 Supabase 项目的回调 URL。同样,你可以在 Supabase Dashboard 的 “Authentication” -> “Providers” -> “GitHub” 中找到它,格式为 `https://<你的项目ID>.supabase.co/auth/v1/callback`。
|
||||
7. 点击 “Register application”。
|
||||
8. **获取 Client ID 和 Client Secret** :
|
||||
9. 注册成功后,页面会显示你的 **Client ID** 。
|
||||
@@ -1061,7 +1063,7 @@ Supabase 的实时功能是其最强大的特性之一,为构建协作文档
|
||||
|
||||
### 5.3.1 数据库实时变动 Postgres Changes
|
||||
|
||||
最常见的 Realtime 功能是对数据库的变更进行实时监听 Postgres Changes 。它允许客户端订阅数据库中特定表、特定行甚至特定列的 INSERT 、 UPDATE 或 DELETE 事件。一旦数据库发生变动(无论是通过 API 调用、Supabase Dashboard 操作,还是 SQL 脚本执行),Supabase 都会利用 PostgreSQL 的底层复制机制,立即通过 WebSocket 将变更的数据推送到所有订阅了该频道的前端客户端,而无需前端通过轮询(Polling)去反复查询。
|
||||
最常见的 Realtime 功能是对数据库的变更进行实时监听 Postgres Changes 。它允许客户端订阅数据库中特定表、特定行甚至特定列的 INSERT 、 UPDATE 或 DELETE 事件。一旦数据库发生变动(无论是通过 API 调用、Supabase Dashboard 操作,还是 SQL 脚本执行),Supabase 都会利用 PostgreSQL 的底层复制机制,立即通过 WebSocket 将变更的数据推送到所有订阅了该频道的前端客户端,而无需前端通过轮询(Polling)去反复查询。
|
||||
|
||||
一般而言,该功能可以在 Table Editor 中找到 Enable Realtime 点击后启动, 但更方便的是通过 SQL 脚本初始化执行,例如:
|
||||
|
||||
@@ -1101,17 +1103,17 @@ END $$;
|
||||
});
|
||||
```
|
||||
|
||||
* `.channel('chat_messages_channel')`: 创建一个隔离的通信频道。
|
||||
* `.on('postgres_changes', ...)`: 这是核心的订阅方法。我们告诉 Supabase 我们只关心 `chat_messages` 表的 `INSERT` 事件。
|
||||
* `payload.new`: 当有新消息被插入数据库时,Supabase 会将这条新数据的完整内容通过 `payload.new` 推送给所有订阅的客户端。
|
||||
* `.subscribe()`: 启动订阅。
|
||||
- `.channel('chat_messages_channel')`: 创建一个隔离的通信频道。
|
||||
- `.on('postgres_changes', ...)`: 这是核心的订阅方法。我们告诉 Supabase 我们只关心 `chat_messages` 表的 `INSERT` 事件。
|
||||
- `payload.new`: 当有新消息被插入数据库时,Supabase 会将这条新数据的完整内容通过 `payload.new` 推送给所有订阅的客户端。
|
||||
- `.subscribe()`: 启动订阅。
|
||||
|
||||
### 5.3.2 信息广播同步 Broadcast & Presence
|
||||
|
||||
对于那些不需要存入数据库的、更“即时”的交互,比如光标移动、在线状态等,Supabase 提供了 Broadcast 和 Presence 功能。
|
||||
|
||||
* Presence: 用于跟踪频道内所有客户端的 **共享状态** 。适合用来实现“谁在线”的功能。
|
||||
* Broadcast: 用于向频道内的所有其他客户端发送**低延迟**的 **临时消息** 。
|
||||
- Presence: 用于跟踪频道内所有客户端的 **共享状态** 。适合用来实现“谁在线”的功能。
|
||||
- Broadcast: 用于向频道内的所有其他客户端发送**低延迟**的 **临时消息** 。
|
||||
|
||||
Presence 的核心思想是: 让每个客户端声明自己的在线状态,并由 Supabase 的服务器负责将这些状态可靠地同步给频道内的所有其他客户端。实现 Presence 分为以下几个关键步骤:
|
||||
|
||||
@@ -1246,7 +1248,7 @@ ch.on('broadcast', { event: 'cursor' }, ({ payload }) => {
|
||||
|
||||
### 5.4.1. Bucket
|
||||
|
||||
Supabase Storage 的组成单元是存储桶 Bucket。你可以把它想象成电脑操作系统中的文件夹。每个 Bucket 都可以有自己独立的安全策略和配置。
|
||||
Supabase Storage 的组成单元是存储桶 Bucket。你可以把它想象成电脑操作系统中的文件夹。每个 Bucket 都可以有自己独立的安全策略和配置。
|
||||
|
||||
Storage 内的所有文件都可以通过一个公开的 URL 直接访问,但并不意味着任何人都可以随意上传或修改,具体的访问权限将由更精细的策略来控制。和数据库一样,Storage 的访问权限也是通过行级安全策略来管理的。SQL 策略写在 storage.objects 和 storage.buckets 这两张特殊表上,可以精确定义谁能读取 (SELECT)、上传 (INSERT)、更新 (UPDATE) 或删除 (DELETE) 文件。
|
||||
|
||||
@@ -1317,9 +1319,9 @@ Edge Function 是 Serverless(无服务器架构)生态中极具核心价值
|
||||
|
||||
目前主流云厂商都推出了各自的 Edge Function 服务,常见的包括:
|
||||
|
||||
* AWS Lambda@Edge:基于 AWS Lambda 延伸的边缘函数服务,可与 CloudFront CDN 联动,支持 Node.js、Python 等语言;
|
||||
* Cloudflare Workers:Cloudflare 推出的边缘函数,部署在其全球 275+ 边缘节点,支持 JavaScript/TypeScript,以 “毫秒级延迟” 为核心优势;
|
||||
* Vercel Edge Functions:适配 Vercel 前端项目的边缘函数,与 Next.js 深度集成,支持 TypeScript,主打 “前端与边缘逻辑无缝衔接”;
|
||||
- AWS Lambda@Edge:基于 AWS Lambda 延伸的边缘函数服务,可与 CloudFront CDN 联动,支持 Node.js、Python 等语言;
|
||||
- Cloudflare Workers:Cloudflare 推出的边缘函数,部署在其全球 275+ 边缘节点,支持 JavaScript/TypeScript,以 “毫秒级延迟” 为核心优势;
|
||||
- Vercel Edge Functions:适配 Vercel 前端项目的边缘函数,与 Next.js 深度集成,支持 TypeScript,主打 “前端与边缘逻辑无缝衔接”;
|
||||
|
||||
回到 Supabase ,当你的应用需要执行 “不能在客户端(浏览器)完成” 的逻辑时,比如用私密密钥调用第三方 API(如 LLM 接口)、处理计算密集型任务(如图片压缩)、或强制执行权限校验(如文件访问规则)时,Supabase Edge Functions 就能发挥作用。它基于 Deno runtime 和 TypeScript 构建,部署在全球边缘节点上,能以 “靠近用户的物理距离” 实现极低的执行延迟,是编写自定义、可信服务器端逻辑的核心工具。
|
||||
|
||||
@@ -1377,8 +1379,7 @@ Supabase 提供了非常友好的界面,让你无需接触命令行即可完
|
||||
8. 在弹出的在线编辑器中, **删除所有默认的占位代码** 。
|
||||
9. 打开你本地的 `llm-chat.ts` 文件, **复制其全部内容** 。
|
||||
10. 将复制的代码**粘贴**到 Supabase 的在线编辑器中。
|
||||
11. **配置****环境变量** ** (Secrets)** :
|
||||
|
||||
11. **配置\*\***环境变量\*\* ** (Secrets)** :
|
||||
1. 在侧边栏找到 Secrets。
|
||||

|
||||
2. Name: 输入 `OPENAI_API_KEY`。
|
||||
@@ -1391,8 +1392,8 @@ Supabase 提供了非常友好的界面,让你无需接触命令行即可完
|
||||
|
||||
如果你想探索更多可能性,可以参考项目中的其他示例。例如:
|
||||
|
||||
* 图片生成 ( txt2img.ts ) : 这个函数展示了如何利用 Edge Function 调用第三方的文生图(Text-to-Image)API(如 Stability AI, Midjourney 等)来动态生成图片。这是一种典型的计算密集型或需要安全调用外部服务的场景。与 llm-chat 案例一样,API 密钥被安全地存储在 Supabase 后端,前端只负责发送文本描述,然后接收并展示生成的图片,整个过程安全、高效。
|
||||
* 发送邮件 ( send-email.ts ) : 在应用中发送欢迎邮件、交易通知或密码重置邮件是常见需求。 send-email.ts 示例演示了如何通过 Edge Function 集成邮件服务(如 Resend, SendGrid)。你无需在客户端代码中暴露敏感的邮件服务 API Key,只需创建一个函数,让前端通过调用这个函数来触发邮件发送。
|
||||
- 图片生成 ( txt2img.ts ) : 这个函数展示了如何利用 Edge Function 调用第三方的文生图(Text-to-Image)API(如 Stability AI, Midjourney 等)来动态生成图片。这是一种典型的计算密集型或需要安全调用外部服务的场景。与 llm-chat 案例一样,API 密钥被安全地存储在 Supabase 后端,前端只负责发送文本描述,然后接收并展示生成的图片,整个过程安全、高效。
|
||||
- 发送邮件 ( send-email.ts ) : 在应用中发送欢迎邮件、交易通知或密码重置邮件是常见需求。 send-email.ts 示例演示了如何通过 Edge Function 集成邮件服务(如 Resend, SendGrid)。你无需在客户端代码中暴露敏感的邮件服务 API Key,只需创建一个函数,让前端通过调用这个函数来触发邮件发送。
|
||||
|
||||
## 5.6 Clerk Login
|
||||
|
||||
@@ -1586,10 +1587,10 @@ serve(async (req) => {
|
||||
})
|
||||
```
|
||||
|
||||
初始化 Supabase 数据表与函数结束后,你还需要在 Clerk 中启用 Webhooks 支持:
|
||||
初始化 Supabase 数据表与函数结束后,你还需要在 Clerk 中启用 Webhooks 支持:
|
||||
|
||||
* 在 Clerk Dashboard -> **Webhooks** 中添加 Endpoint,填入Supabase Edge Function 的 URL。
|
||||
* 勾选 `user.created`, `user.updated`, `user.deleted` 等事件。
|
||||
- 在 Clerk Dashboard -> **Webhooks** 中添加 Endpoint,填入Supabase Edge Function 的 URL。
|
||||
- 勾选 `user.created`, `user.updated`, `user.deleted` 等事件。
|
||||
|
||||

|
||||
|
||||
@@ -1599,8 +1600,8 @@ serve(async (req) => {
|
||||
|
||||
在深入了解如何对 Clerk 支持第三方登录前,我们先明确两个核心概念:开发环境与生产环境,这是软件从 “开发测试” 到 “上线可用” 的两个关键阶段,二者的定位、用途和安全要求截然不同:
|
||||
|
||||
* 开发环境:开发者本地或测试服务器使用的环境,仅用于功能开发、调试和内部验证(如本地 localhost:3000 服务),不对外开放
|
||||
* 生产环境:应用正式上线后,面向真实用户的公开环境(如部署在 Vercel、阿里云等平台的 https://my-app.com)
|
||||
- 开发环境:开发者本地或测试服务器使用的环境,仅用于功能开发、调试和内部验证(如本地 localhost:3000 服务),不对外开放
|
||||
- 生产环境:应用正式上线后,面向真实用户的公开环境(如部署在 Vercel、阿里云等平台的 https://my-app.com)
|
||||
|
||||
而 Clerk 对社交登录区分这两种环境,本质是平衡 “开发效率” 与 “生产安全”:开发阶段需减少冗余配置以快速验证功能,生产阶段需通过专属凭证保障数据安全,同时符合 Google、GitHub 等第三方 OAuth 平台的规则(线上应用必须绑定专属域名与凭证,不允许使用共享资源)。下面具体说明两种环境下 Clerk 社交登录的差异配置:
|
||||
|
||||
@@ -1608,10 +1609,10 @@ serve(async (req) => {
|
||||
|
||||
开发环境中,Clerk 已预置共享 OAuth 凭证和默认重定向 URI,无需前往 GitHub/Google 申请专属凭证,操作步骤如下:
|
||||
|
||||
* 登录 Clerk Dashboard ,在左侧导航栏进入 SSO connections (SSO 连接)页面。
|
||||
* 点击 Add connection (添加连接),选择 For all users (对所有用户生效)。
|
||||
* 在 Choose provider (选择提供商)下拉菜单中,按需选择 GitHub 或 Google 。
|
||||
* 直接点击 Add connection (添加连接),Clerk 会自动用共享凭证完成绑定。
|
||||
- 登录 Clerk Dashboard ,在左侧导航栏进入 SSO connections (SSO 连接)页面。
|
||||
- 点击 Add connection (添加连接),选择 For all users (对所有用户生效)。
|
||||
- 在 Choose provider (选择提供商)下拉菜单中,按需选择 GitHub 或 Google 。
|
||||
- 直接点击 Add connection (添加连接),Clerk 会自动用共享凭证完成绑定。
|
||||
|
||||
配置后,本地启动应用(如 `localhost:3000`)并点击“Sign in with GitHub/Google”,Clerk 会自动代理登录请求,快速验证功能是否正常。
|
||||
|
||||
@@ -1621,23 +1622,23 @@ serve(async (req) => {
|
||||
|
||||
应用部署上线(如 Vercel、阿里云)并切换到 Clerk Production Instance 后,共享凭证失效,需为 GitHub/Google 配置自定义 OAuth 凭证(建议同时打开 Clerk Dashboard 和第三方平台页面,方便同步操作):
|
||||
|
||||
* 前置通用操作(Clerk 控制台):
|
||||
* 进入 Clerk SSO connections 页面,点击 Add connection → 选择 For all users 。
|
||||
* 选择目标平台(GitHub/Google),确保开启 Enable for sign-up and sign-in (允许注册登录)和 Use custom credentials (使用自定义凭证)。
|
||||
* 复制页面中的 Authorization Callback URL (GitHub)或 Authorized Redirect URI (Google),保存到安全位置,不要关闭当前页面/弹窗。
|
||||
* 2.1 GitHub 平台配置:
|
||||
* 登录 GitHub,进入 Developer Settings (路径:头像 → Settings → Developer settings → OAuth Apps)。
|
||||
* 点击 New OAuth app ,填写信息:`Application name`(应用名称)、`Homepage URL`(生产域名,如 `https://my-app.com`)、`Authorization Callback URL`(粘贴从 Clerk 复制的地址)。
|
||||
* 点击 Register application ,再点击 Generate a new client secret ,保存生成的 Client ID 和 Client Secret (Secret 仅显示一次)。
|
||||
* 回到 Clerk 弹窗,粘贴 Client ID 和 Client Secret,点击 Add connection 完成配置(若关闭弹窗,可在 SSO connections 找到 GitHub 连接,在“Use custom credentials”模块补填)。
|
||||
* 2.2 Google 平台配置:
|
||||
* 登录 Google Cloud Console ,选择已有项目或新建项目(如“My App Production”)。
|
||||
* 点击左上角菜单 → APIs & Services → Credentials ,点击 Create Credentials → OAuth client ID (首次配置需先完成 OAuth consent screen 设置,选择“External”并填写应用信息)。
|
||||
* 选择 Application type 为 Web application ,配置:
|
||||
- 前置通用操作(Clerk 控制台):
|
||||
- 进入 Clerk SSO connections 页面,点击 Add connection → 选择 For all users 。
|
||||
- 选择目标平台(GitHub/Google),确保开启 Enable for sign-up and sign-in (允许注册登录)和 Use custom credentials (使用自定义凭证)。
|
||||
- 复制页面中的 Authorization Callback URL (GitHub)或 Authorized Redirect URI (Google),保存到安全位置,不要关闭当前页面/弹窗。
|
||||
- 2.1 GitHub 平台配置:
|
||||
- 登录 GitHub,进入 Developer Settings (路径:头像 → Settings → Developer settings → OAuth Apps)。
|
||||
- 点击 New OAuth app ,填写信息:`Application name`(应用名称)、`Homepage URL`(生产域名,如 `https://my-app.com`)、`Authorization Callback URL`(粘贴从 Clerk 复制的地址)。
|
||||
- 点击 Register application ,再点击 Generate a new client secret ,保存生成的 Client ID 和 Client Secret (Secret 仅显示一次)。
|
||||
- 回到 Clerk 弹窗,粘贴 Client ID 和 Client Secret,点击 Add connection 完成配置(若关闭弹窗,可在 SSO connections 找到 GitHub 连接,在“Use custom credentials”模块补填)。
|
||||
- 2.2 Google 平台配置:
|
||||
- 登录 Google Cloud Console ,选择已有项目或新建项目(如“My App Production”)。
|
||||
- 点击左上角菜单 → APIs & Services → Credentials ,点击 Create Credentials → OAuth client ID (首次配置需先完成 OAuth consent screen 设置,选择“External”并填写应用信息)。
|
||||
- 选择 Application type 为 Web application ,配置:
|
||||
1. `Authorized JavaScript origins`:添加生产域名(如 `https://my-app.com`、`https://www.my-app.com`),本地验证可补充 `http://localhost:端口号`。
|
||||
2. `Authorized Redirect URIs`:粘贴从 Clerk 复制的地址。
|
||||
* 点击 Create ,保存弹窗中的 Client ID 和 Client Secret ,回到 Clerk 弹窗粘贴并点击 Add connection 。
|
||||
* 关键注意事项:
|
||||
- 点击 Create ,保存弹窗中的 Client ID 和 Client Secret ,回到 Clerk 弹窗粘贴并点击 Add connection 。
|
||||
- 关键注意事项:
|
||||
1. 禁止 WebView 登录:Google OAuth 不支持应用内浏览器登录,需参考 [Google 官方文档](https://support.google.com/cloud/answer/7657789) 调整。
|
||||
2. 切换发布状态:默认“Testing”状态仅支持 100 个测试用户,需在 OAuth consent screen 将“Publishing status”改为 In production (需通过 Google 审核)。
|
||||
3. 阻止子邮箱:Clerk 默认拦截含 `+`/`=`/`#` 的 Google 邮箱(如 `user+alias@example.com`),可在 Google 连接详情页开启/关闭 Block email subaddresses (建议开启提升安全性)。
|
||||
@@ -1647,11 +1648,11 @@ serve(async (req) => {
|
||||
|
||||
配置完成后,通过 Clerk 内置 Account Portal 验证功能:
|
||||
|
||||
* 进入 Clerk Dashboard,左侧导航栏进入 Account Portal 页面。
|
||||
* 在“Sign-in”模块右侧,点击“访问登录页面”按钮,跳转至对应环境登录页:
|
||||
* 开发环境:`https://你的域名.accounts.dev/sign-in`(如 `https://my-app.accounts.dev/sign-in`)。
|
||||
* 生产环境:`https://accounts.你的域名.com/sign-in`(如 `https://accounts.my-app.com/sign-in`)。
|
||||
* 点击“Sign in with GitHub/Google”,用对应平台账号登录,若能成功跳转并返回应用,说明连接配置正常。
|
||||
- 进入 Clerk Dashboard,左侧导航栏进入 Account Portal 页面。
|
||||
- 在“Sign-in”模块右侧,点击“访问登录页面”按钮,跳转至对应环境登录页:
|
||||
- 开发环境:`https://你的域名.accounts.dev/sign-in`(如 `https://my-app.accounts.dev/sign-in`)。
|
||||
- 生产环境:`https://accounts.你的域名.com/sign-in`(如 `https://accounts.my-app.com/sign-in`)。
|
||||
- 点击“Sign in with GitHub/Google”,用对应平台账号登录,若能成功跳转并返回应用,说明连接配置正常。
|
||||
|
||||
# 6. 从 Supabase 到更多后端开发组件(进阶)
|
||||
|
||||
@@ -1659,9 +1660,9 @@ serve(async (req) => {
|
||||
|
||||
但从更长期、更工程化的角度来看, **Supabase 提供的每一块能力(Auth / Storage / Edge Functions / Realtime / Database),在业界几乎都有对应的专业替代方案** ——既包括同类 BaaS 平台,也包括更“单点突破”的云服务和开源组件。作为上进的个人开发者和初创团队来说,了解这些替代选项有几个好处:
|
||||
|
||||
* 判断当前项目是否“全用 Supabase 就够了”,还是某一块需要更专业/更便宜/更易合规的专用服务;
|
||||
* 当项目规模变大或需求变复杂时,是否可以把某个模块从 Supabase 替换出去(例如改用专门的 Auth 平台或对象存储),而不是一开始就被平台彻底锁死;
|
||||
* 拓宽技术选型视野,即使暂时不更换,也能大致知道“如果不用 Supabase 的 X 功能,我还有哪些常见选择”。
|
||||
- 判断当前项目是否“全用 Supabase 就够了”,还是某一块需要更专业/更便宜/更易合规的专用服务;
|
||||
- 当项目规模变大或需求变复杂时,是否可以把某个模块从 Supabase 替换出去(例如改用专门的 Auth 平台或对象存储),而不是一开始就被平台彻底锁死;
|
||||
- 拓宽技术选型视野,即使暂时不更换,也能大致知道“如果不用 Supabase 的 X 功能,我还有哪些常见选择”。
|
||||
|
||||
本节将分别介绍 Supabase 所覆盖的几大能力在市场上的主流替代方案,例如:认证(Auth)、文件存储(Storage)、边缘函数(Edge Functions)、实时通信(Realtime)、数据库托管等。简单对比它们在功能特性、免费额度/定价、易用性以及社区流行度等方面的差异, 让你对后端组件工具库有更全面的理解。
|
||||
|
||||
@@ -1674,7 +1675,7 @@ serve(async (req) => {
|
||||
| Firebase(Google) | 全托管 BaaS(Auth + Firestore + Storage + Functions + Hosting) | Spark:免费轻量额度;Blaze:按量计费(Firestore/Storage/Functions 分别算) | 行业最成熟、文档好、上手快、实时能力强。适用于中小型产品、移动/前端主导团队。缺点:计费复杂、锁定性强、查询限制多(尤其 Firestore)。 |
|
||||
| Supabase | 开源 BaaS(Postgres + Auth + Storage + Edge Functions + Realtime) | 免费:500MB DB、1GB Storage、无服务器函数少量调用;Pro:按实例计费 | 最像 Firebase 的 SQL 版;界面优秀、体验现代、可自托管。适用于需要强 SQL、BI、事务能力的应用。缺点:高并发或复杂函数成本较高。 |
|
||||
| Appwrite Cloud | 开源一站式 BaaS(DB + Auth + Storage + Functions + Realtime) | 免费:包含基本 DB/Storage/FaaS;付费按资源级别计费 | 体验现代化、API 统一、可自托管;适合开发者友好的应用快速迭代。缺点:生态还不如 Firebase/Supabase 成熟;性能在大型应用中需要测试。 |
|
||||
| Nhost | Postgres + GraphQL + Auth + Storage + Functions | 免费:1GB DB、1GB Storage、少量函数调用 | 类似“Supabase + Hasura”;天然 GraphQL;适合前端团队与 React/Next.js 项目。缺点:生态小、成本随用量升高。 |
|
||||
| Nhost | Postgres + GraphQL + Auth + Storage + Functions | 免费:1GB DB、1GB Storage、少量函数调用 | 类似“Supabase + Hasura”;天然 GraphQL;适合前端团队与 React/Next.js 项目。缺点:生态小、成本随用量升高。 |
|
||||
| AWS Amplify | AWS 一站式后端(Cognito + AppSync + DynamoDB + Storage + Functions + Hosting) | 免费:Hosting 额度 + Cognito 10k MAU + 部分函数额度 | 大而全,适合已有 AWS 基础的团队;企业级可靠性。缺点:最难上手,服务碎片化;初创团队维护成本高。 |
|
||||
| Xata(近两年快速增长) | 多模型数据库 + Auth + Edge Functions | 免费:250k 记录、15GB 带宽 | 虽然更偏「DB + API」,但提供 Auth、文件、逻辑,可作为轻量全栈后端。UI/开发体验极佳。缺点:功能不如 Firebase/Supabase 全面。 |
|
||||
| Convex(开发者体验极强) | 托管数据库 + Auth + Functions(前端优先) | 免费开发版;付费按请求量计费 | 极简上手;无需 schema;前端写函数即可用后端。适合 MVP/快速验证。缺点:高度绑定平台,迁移成本高;不算完全传统 BaaS。 |
|
||||
|
||||
Reference in New Issue
Block a user