大数跨境

从零打造:我的第一个 Serverless 全栈待办事项应用

从零打造:我的第一个 Serverless 全栈待办事项应用 点尚电商
2026-03-27
2
导读:在这个云原生时代,作为一个开发者,拥有一个完全属于自己的全栈项目是很多人的梦想。
在这个云原生时代,作为一个开发者,拥有一个完全属于自己的全栈项目是很多人的梦想。但一想到要买服务器、装环境、搞运维、备份数据库,很多人就望而却步了。
今天,我想分享我的第一个 Serverless 网站开发之旅——**MyTodoList**。它不需要服务器,不用担心运维,甚至不需要花一分钱就能上线运行。

### 一、为什么:为什么选择 Serverless?

传统的 web 开发,我们不仅要做“程序员”,还要做“运维工程师”。服务器要钱、带宽要钱、安全防护要自己搞。对于个人项目或者小型 MVP(最小可行性产品)来说,这太重了。
**Serverless(无服务器架构)** 的出现改变了这一切。它的核心理念是:**No Ops(无运维)**。你只需要关注核心业务代码,服务的运行、扩容、负载均衡全部交给云厂商处理。
对于个人开发者,Serverless 的吸引力是致命的:
  1. **省钱**:按量付费,没人访问时不花钱。
  2. **省心**:不用担心服务器宕机,不用担心被黑客暴力破解 SSH。
  3. **高效**:从开发到上线,可能只需要一个小时。

### 二、是什么:MyTodoList 项目介绍

带着对 Serverless 的憧憬,我开发了一个轻量级的待办事项管理应用——**MyTodoList**。
这是一个典型的“单页应用(SPA)”,具备以下核心功能:
  • 用户认证:安全的登录系统,支持 Token 鉴权。
  • 看板管理:三栏布局(需要做的、已完成、推迟备选),支持状态流转。
  • 智能筛选:支持关键词搜索、时间段筛选。
  • 响应式设计:完美适配手机和电脑,移动端体验优化到了像素级。
最重要的是,它的前端代码(HTML/CSS/JS)和后端代码全部写在一个文件里,部署在 **Cloudflare Workers** 上,数据存储在 **Cloudflare KV** 中。

### 三、有什么优势:技术架构的取舍

在这个项目中,最大的技术亮点是对 **Cloudflare KV** 数据库的巧妙运用。
KV 是一个键值对数据库,它不像 MySQL 那样支持复杂的查询。为了实现搜索和筛选功能,我最初设计了“双写策略”:既存一份“任务详情”,又存一份“任务索引”。
但在实际开发中,我发现对于个人应用,这完全是一种冗余。于是,我大胆地砍掉了单独的详情存储,**只保留一个巨大的“任务索引” Key**,里面包含了所有任务的完整数据。
**这种架构的优势在于:**
  1. **极简**:代码逻辑减少了 40%,不再需要同步索引和详情。
  2. **极速**:前端只需一次请求就能拿到所有数据,搜索和筛选在浏览器内存中瞬间完成,体验如丝般顺滑。
  3. **低成本**:KV 的读写次数大幅降低。

### 四、如何实现:以项目为实例说明

让我们看看核心的“单文件架构”是如何工作的。

1. 前后端一体化

在 Cloudflare Workers 中,我们可以直接返回 HTML 字符串作为前端页面。
function getFrontendHTML() {  return `    <!DOCTYPE html>    <html>    ...这里是所有的 HTML/CSS/JS 代码...    </html>  `;}
async function handleRequest(request) {  const url = new URL(request.url);  // 路由分发  if (url.pathname === '/') {    return new Response(getFrontendHTML(), {headers: {'Content-Type': 'text/html'}});  }  if (url.pathname.startsWith('/api/')) {    return handleAPI(request); // 处理后端接口  }}

2. 数据操作逻辑

由于所有数据都在一个 Key (`task_index`) 里,更新数据变得非常直观:读出来 -> 改数据 -> 存回去。
async function handleTasksAPI(request, env) {  // 读取全量数据  let index = await env.TODOLIST_KV.get('task_index', { type: 'json' }) || [];
  // 新增任务  if (method === 'POST') {    const newTask = { id: generateId(), title: body.title, ... };    index.unshift(newTask); // 放入数组头部    await env.TODOLIST_KV.put('task_index', JSON.stringify(index));  }
  // 更新/删除逻辑类似:找到那条数据 -> 修改 -> 覆盖写入}
虽然听起来“读全量数据”有点重,但经过计算,25MB 的 KV 空间足以存储 **10万条** 待办事项。对于个人使用,这简直是“海量”存储,且读取速度通常在 50ms 以内。

### 五、QA 问答

在开发过程中,我也遇到了很多典型的技术疑问,这里整理了几个最关键的 Q&A:
**Q1:所有任务都在一个 Key 里,数据量超过 KV 限制(25MB)怎么办?**
**A:** 这是一个好问题。经过测算,一条任务大约 200 字节,25MB 可以存储约 12.5 万条任务。对于个人应用,这几乎不可能触达。如果真的触达了,解决方案也很简单:可以按状态分片存储(如 `index_todo`, `index_completed`),或者迁移到 Cloudflare D1(SQL 数据库)。
**Q2:修改一条任务时,是不是要把整个 10MB 的数据全量回传?**
**A:** 是的,这是 KV 数据库的特性。用户端只传单条数据给服务器,但服务器在写入时,确实需要读取并写回全量数据。虽然听起来低效,但在 10MB 级别下,网络传输和内存操作都在毫秒级,完全不影响体验。这也是架构权衡的结果——用“写放大”换取“读极速”和“代码极简”。
**Q3:如何清理过期的用户 Token?需要写定时任务吗?**
**A:** 完全不需要!Cloudflare KV 原生支持 `expirationTtl` 参数。我们在存 Token 时设置 24 小时过期,KV 会自动在到期后物理删除数据,零成本实现垃圾回收。
**Q4:如何把数据导出到 MySQL 备份?**
**A:** 既然数据全在前端内存里,导出就非常简单。只需在浏览器控制台运行一段 JS 代码,将 `allTasks` 数组遍历生成 CSV 字符串,触发下载即可。不需要复杂的后端导出接口。

### 六、总结

通过 MyTodoList 这个项目,我切身体会到了 Serverless 的魅力。它不是简单的“不用买服务器”,而是一种全新的开发模式:**关注点分离**。
我们将复杂的运维剥离,只保留最纯粹的业务逻辑。虽然 KV 数据库在处理超大规模数据时有其局限性,但通过合理的架构设计(单文件索引),它在中小型应用场景下展现出了惊人的开发效率和运行性能。
如果你也想拥有一个自己的全栈项目,不妨从 Cloudflare Workers 开始,体验一下这种“代码写完即上线”的快乐吧!
---
*感兴趣的朋友可以 关注公众号 回复mytodolist 获取完整源码,一起探索 Serverless 的无限可能。*

【声明】内容源于网络
0
0
点尚电商
1234
内容 1
粉丝 0
点尚电商 1234
总阅读0
粉丝0
内容1