PocketEgg 架构示意:小程序 + 云开发,零运维服务器

做 PocketEgg(习惯养成小程序)的时候,我面临一个典型的独立开发者困境:既要写前端,又要写后端,还要管服务器、配数据库、搞 HTTPS 证书……一个人精力实在有限。

最后选择了微信「云开发」方案,整个后端部分几乎没有写传统意义上的"服务器代码",部署和运维成本接近于零。这篇文章聊聊这套方案的具体用法和踩过的坑。

本文目录
  1. 1. 为什么选云开发,而不是自建后端
  2. 2. 云数据库:用集合代替表
  3. 3. 云函数:写业务逻辑的地方
  4. 4. 云存储与CDN
  5. 5. 几个真实踩过的坑
  6. 6. 成本与限制

1. 为什么选云开发,而不是自建后端

自建后端(比如 Node.js + Express + MySQL)的优势是灵活、可控,但代价是:

对于一个还没验证市场需求的小项目,这些成本前置投入太大。微信云开发把这些都封装好了——数据库、文件存储、云函数、定时任务、甚至 HTTPS 都是开箱即用的,而且和小程序的鉴权体系(openid)天然集成,不需要自己写登录注册。

2. 云数据库:用集合代替表

云开发的数据库是基于 MongoDB 的,概念上是"集合(Collection)"而不是"表",每条记录是一个 JSON 文档,不需要预先定义字段结构,这对快速迭代特别友好。

miniprogram/pages/habit/index.js
// 在小程序端直接读写数据库(受安全规则控制)
const db = wx.cloud.database()

// 新增一条打卡记录
await db.collection('checkins').add({
  data: {
    habitId: 'habit_001',
    date: formatDate(new Date()),
    _openid: // 自动注入,无需手动传递
  }
})
安全规则是关键: 云数据库的"安全规则"决定了客户端能否直接读写。默认规则是"仅创建者可读写自己的数据",这对大多数小程序场景已经足够,避免了写一套完整的权限校验后端逻辑。

3. 云函数:写业务逻辑的地方

有些逻辑不适合放在客户端执行(比如涉及多用户数据的统计、需要调用第三方API、需要服务端密钥的操作),这时候就用云函数。云函数本质上是部署在云端的 Node.js 函数,按调用次数计费。

cloudfunctions/getStreakStats/index.js
const cloud = require('wx-server-sdk')
cloud.init()

exports.main = async (event, context) => {
  const { OPENID } = cloud.getWXContext()
  const db = cloud.database()

  // 统计该用户连续打卡天数(聚合查询,客户端无法直接做)
  const records = await db.collection('checkins')
    .where({ _openid: OPENID })
    .orderBy('date', 'desc')
    .get()

  return { streak: calcStreak(records.data) }
}

PocketEgg 里所有涉及"积分计算"、"排行榜统计"、"成就解锁判定"的逻辑,都放在云函数里,避免客户端被篡改数据。

4. 云存储与CDN

用户上传的头像、习惯图标这类文件,存在云存储里,自带 CDN 加速,不需要额外配置七牛云或阿里云OSS。上传逻辑也很简单:

utils/upload.js
const res = await wx.cloud.uploadFile({
  cloudPath: `avatars/${openid}.png`,
  filePath: tempFilePath // 用户选择的图片临时路径
})
// res.fileID 即可直接用于 <image> 组件展示

5. 几个真实踩过的坑

6. 成本与限制

云开发有免费额度(数据库读写次数、云函数调用次数、存储空间都有每日/每月免费量),PocketEgg 早期用户量不大的时候完全在免费额度内,超出之后按量计费,整体成本远低于自己租服务器。

需要注意的限制是:云开发深度绑定微信生态,如果未来要做多端(比如同时支持App、H5),数据层需要做额外的适配工作。但对于"只做微信小程序"的项目,这几乎是性价比最高的选择。

🦆

CocoDuck

独立开发者 & 设计工程师,正在用代码孵化各种小而美的产品。