第8课:云函数开发与部署
本课系统讲解CloudBase云函数开发全流程。课程涵盖:1)云函数架构设计原则,包括单一职责、统一入口、错误处理和日志记录;2)标准模板实现,演示基础结构、路由函数和CRUD操作;3)完整宠物服务实战案例;4)多种部署方式(手动/命令行/批量脚本);5)本地与云端测试方法。通过本课学习,学员将掌握云函数开发、部署、测试全流程技能,并理解日志记录、错误处理等关键实践。下节课将转入小程序UI设计与性
·
📚 课程目标
本课将深入讲解CloudBase云函数的开发、部署和优化。你将学会如何设计云函数架构、实现业务逻辑、处理错误、记录日志,以及如何高效地部署和测试云函数。
🏗️ 云函数架构设计
架构原则
- 单一职责:每个云函数只负责一个业务模块
- 统一入口:通过action参数路由不同功能
- 错误处理:统一的错误捕获和返回格式
- 日志记录:完整的操作日志便于调试
云函数调用关系图

💻 云函数标准模板
1. 基础结构模板
// cloudfunctions/pet_service_template/index.js
const cloud = require('wx-server-sdk');
// 初始化云开发环境
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV // 使用当前云环境
});
// 获取数据库引用
const db = cloud.database();
const _ = db.command;
/**
* 云函数入口
* @param {Object} event - 前端传入的参数
* @param {Object} context - 云函数上下文
*/
exports.main = async (event, context) => {
// 获取调用者信息
const { OPENID, APPID, UNIONID } = cloud.getWXContext();
// 记录请求日志
console.log('[CloudFunction] 请求开始', {
action: event.action,
openid: OPENID,
timestamp: new Date().toISOString()
});
try {
// 路由到具体处理函数
const result = await routeAction(event, context);
// 记录成功日志
console.log('[CloudFunction] 请求成功', {
action: event.action,
success: true
});
return {
success: true,
data: result,
timestamp: new Date().toISOString()
};
} catch (error) {
// 记录错误日志
console.error('[CloudFunction] 请求失败', {
action: event.action,
error: error.message,
stack: error.stack
});
return {
success: false,
error: error.message,
code: error.code || 'UNKNOWN_ERROR',
timestamp: new Date().toISOString()
};
}
};
/**
* 路由函数
*/
async function routeAction(event, context) {
const { action } = event;
// 验证action参数
if (!action) {
throw new Error('缺少action参数');
}
// 根据action路由到不同处理函数
switch (action) {
case 'create':
return await handleCreate(event);
case 'update':
return await handleUpdate(event);
case 'delete':
return await handleDelete(event);
case 'query':
return await handleQuery(event);
case 'list':
return await handleList(event);
default:
throw new Error(`未知的action: ${action}`);
}
}
/**
* 处理创建操作
*/
async function handleCreate(event) {
const { data } = event;
// 数据验证
validateData(data);
// 添加时间戳
const recordData = {
...data,
created_time: new Date(),
updated_time: new Date()
};
// 插入数据库
const result = await db.collection('your_collection').add({
data: recordData
});
console.log('[handleCreate] 创建成功', { id: result._id });
return {
id: result._id,
message: '创建成功'
};
}
/**
* 处理更新操作
*/
async function handleUpdate(event) {
const { id, data } = event;
if (!id) {
throw new Error('缺少id参数');
}
// 数据验证
validateData(data);
// 更新数据
const updateData = {
...data,
updated_time: new Date()
};
await db.collection('your_collection').doc(id).update({
data: updateData
});
console.log('[handleUpdate] 更新成功', { id });
return {
message: '更新成功'
};
}
/**
* 处理删除操作(软删除)
*/
async function handleDelete(event) {
const { id } = event;
if (!id) {
throw new Error('缺少id参数');
}
// 软删除:标记为已删除
await db.collection('your_collection').doc(id).update({
data: {
is_deleted: true,
deleted_time: new Date()
}
});
console.log('[handleDelete] 删除成功', { id });
return {
message: '删除成功'
};
}
/**
* 处理查询操作
*/
async function handleQuery(event) {
const { id } = event;
if (!id) {
throw new Error('缺少id参数');
}
const { data } = await db.collection('your_collection')
.doc(id)
.get();
if (!data) {
throw new Error('数据不存在');
}
console.log('[handleQuery] 查询成功', { id });
return data;
}
/**
* 处理列表查询
*/
async function handleList(event) {
const {
page = 1,
pageSize = 20,
filter = {},
orderBy = 'created_time',
order = 'desc'
} = event;
// 构建查询条件
const where = {
is_deleted: false,
...filter
};
// 查询总数
const countResult = await db.collection('your_collection')
.where(where)
.count();
// 查询列表
const { data: list } = await db.collection('your_collection')
.where(where)
.orderBy(orderBy, order)
.skip((page - 1) * pageSize)
.limit(pageSize)
.get();
console.log('[handleList] 查询成功', {
total: countResult.total,
page,
pageSize
});
return {
list: list,
total: countResult.total,
page: page,
pageSize: pageSize,
totalPages: Math.ceil(countResult.total / pageSize)
};
}
/**
* 数据验证函数
*/
function validateData(data) {
if (!data || typeof data !== 'object') {
throw new Error('无效的数据格式');
}
// 根据实际业务添加验证逻辑
// 例如:
// if (!data.name || data.name.length > 50) {
// throw new Error('名称不能为空且长度不能超过50');
// }
}
2. 云函数配置文件
// cloudfunctions/pet_service_template/config.json
{
"permissions": {
"openapi": []
},
"timeout": 10,
"envVariables": {
"ENV_ID": "{{env.ENV_ID}}"
}
}
// cloudfunctions/pet_service_template/package.json
{
"name": "pet_service_template",
"version": "1.0.0",
"description": "云函数模板",
"main": "index.js",
"dependencies": {
"wx-server-sdk": "~2.6.3"
}
}
🛠️ 实战案例:宠物服务云函数
完整的宠物管理云函数
// cloudfunctions/pet_pet_service/index.js
const cloud = require('wx-server-sdk');
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
const db = cloud.database();
const _ = db.command;
exports.main = async (event, context) => {
console.log('[pet_pet_service] 请求:', event);
try {
const result = await routeAction(event);
return { success: true, data: result };
} catch (error) {
console.error('[pet_pet_service] 错误:', error);
return {
success: false,
error: error.message,
code: error.code || 'UNKNOWN_ERROR'
};
}
};
async function routeAction(event) {
const { action } = event;
switch (action) {
case 'createPet':
return await createPet(event);
case 'updatePet':
return await updatePet(event);
case 'deletePet':
return await deletePet(event);
case 'getPetList':
return await getPetList(event);
case 'getPetDetail':
return await getPetDetail(event);
default:
throw { code: 'INVALID_ACTION', message: '未知操作' };
}
}
// 创建宠物档案
async function createPet(event) {
const { userId, petData } = event;
// 验证必填字段
if (!petData.name || !petData.type || !petData.breed) {
throw { code: 'INVALID_DATA', message: '缺少必填字段' };
}
// 计算每日热量需求
const dailyCalories = calculateDailyCalories(petData);
// 创建记录
const result = await db.collection('pet_pets').add({
data: {
user_id: userId,
name: petData.name,
type: petData.type,
breed: petData.breed,
gender: petData.gender,
age: petData.age,
weight: petData.weight,
health_status: petData.health_status || 'healthy',
special_needs: petData.special_needs || [],
activity_level: petData.activity_level,
daily_calories: dailyCalories,
created_time: new Date(),
updated_time: new Date(),
is_deleted: false
}
});
// 更新用户宠物数量
await db.collection('pet_users').doc(userId).update({
data: {
'stats.pet_count': _.inc(1),
updated_time: new Date()
}
});
console.log('[createPet] 创建成功', { petId: result._id });
return {
petId: result._id,
message: '宠物档案创建成功'
};
}
// 获取宠物列表
async function getPetList(event) {
const { userId } = event;
const { data: petList } = await db.collection('pet_pets')
.where({
user_id: userId,
is_deleted: false
})
.orderBy('created_time', 'desc')
.get();
console.log('[getPetList] 查询成功', { count: petList.length });
return {
pet_list: petList,
total: petList.length
};
}
// 获取宠物详情
async function getPetDetail(event) {
const { petId } = event;
const { data } = await db.collection('pet_pets').doc(petId).get();
if (!data) {
throw { code: 'PET_NOT_FOUND', message: '宠物不存在' };
}
// 获取最近的健康记录
const { data: recentRecords } = await db.collection('pet_health_records')
.where({ pet_id: petId })
.orderBy('record_date', 'desc')
.limit(5)
.get();
return {
...data,
recent_health_records: recentRecords
};
}
// 计算每日热量需求
function calculateDailyCalories(petData) {
const RER = 70 * Math.pow(petData.weight, 0.75);
let multiplier = 1.6;
if (petData.age < 1) {
multiplier = 2.0;
} else if (petData.age > 7) {
multiplier = 1.2;
}
const activityMultiplier = {
'low': 1.2,
'medium': 1.5,
'high': 1.8
};
return Math.round(RER * multiplier *
(activityMultiplier[petData.activity_level] || 1.5));
}
🚀 云函数部署
1. 手动部署(微信开发者工具)
# 步骤:
1. 在微信开发者工具中打开项目
2. 找到云函数目录
3. 右键点击要部署的云函数文件夹
4. 选择"云函数增量上传"或"云函数全量上传"
5. 等待上传完成
2. 命令行部署
# 安装云开发CLI工具
npm install -g @cloudbase/cli
# 登录
tcb login
# 部署单个云函数
tcb functions:deploy pet_pet_service
# 部署所有云函数
tcb functions:deploy --all
3. 批量部署脚本
#!/bin/bash
# deploy-all-functions.sh
echo "开始部署所有云函数..."
# 定义所有云函数列表
functions=(
"pet_user_service"
"pet_pet_service"
"pet_ai_expert_service"
"pet_recommendation_service"
"pet_health_analysis"
)
# 循环部署
for func in "${functions[@]}"; do
echo "----------------------------------------"
echo "部署云函数: $func"
echo "----------------------------------------"
cd "cloudfunctions/$func" || exit
# 安装依赖
echo "安装依赖..."
npm install
# 返回根目录
cd ../..
# 部署云函数
echo "上传云函数..."
tcb functions:deploy "$func"
if [ $? -eq 0 ]; then
echo "✅ $func 部署成功"
else
echo "❌ $func 部署失败"
exit 1
fi
echo ""
done
echo "========================================="
echo "所有云函数部署完成!"
echo "========================================="
🧪 云函数测试
1. 本地测试
// test/pet_pet_service.test.js
const assert = require('assert');
// 模拟云函数
async function testCreatePet() {
const event = {
action: 'createPet',
userId: 'test_user_123',
petData: {
name: '旺财',
type: 'dog',
breed: 'golden_retriever',
gender: 'male',
age: 2,
weight: 28.5,
activity_level: 'high'
}
};
// 这里应该调用实际的云函数
// const result = await cloudFunction(event);
console.log('测试创建宠物档案...');
// assert.strictEqual(result.success, true);
console.log('✅ 测试通过');
}
testCreatePet();
2. 云端测试
在微信开发者工具中:
// 工具 -> 云开发 -> 云函数 -> 选择函数 -> 右键测试
// 测试参数
{
"action": "getPetList",
"userId": "user_12345678"
}
📊 本课总结
完成本课后,你已经掌握:
- ✅ 云函数标准架构设计
- ✅ 统一的错误处理机制
- ✅ 完整的日志记录方案
- ✅ 云函数部署流程
- ✅ 测试与调试方法
🎓 下节预告
在第9课中,我们将学习:
- 微信小程序UI设计规范
- 组件化开发最佳实践
- 页面性能优化技巧
- 用户体验提升方案
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)