AGC云函数进阶:编写复杂逻辑服务鸿蒙5应用

前言
鸿蒙5(HarmonyOS 5)与AppGallery Connect(AGC)云函数的深度结合,为开发者提供了强大的云端逻辑处理能力。本文将深入探讨如何利用AGC云函数构建复杂业务逻辑,实现鸿蒙5应用的前后端解耦,涵盖从基础开发到高级应用的全套解决方案。

一、云函数核心优势
​​无服务器架构​​:无需管理基础设施
​​弹性扩展​​:自动应对流量变化
​​多语言支持​​:Node.js、Python、Java等
​​无缝集成​​:与AGC其他服务(数据库、认证等)深度整合
二、环境准备
2.1 开通云函数服务
登录AGC控制台
进入项目 > 选择应用 > 选择"云函数"服务
点击"立即开通"
2.2 安装Cloud CLI工具

安装AGC CLI

npm install -g @agconnect/cli

登录AGC

agc cloud login

初始化云函数项目

agc cloud functions init --project MyHarmonyFunctions
三、基础云函数开发
3.1 创建简单云函数(Node.js)
// functions/hello-world/index.js
const cloud = require('@agconnect/cloud-function');

exports.handler = async (request, response) => {
try {
const name = request.query.name || request.body.name || 'World';

response.status(200).send({
  message: `Hello ${name}!`,
  timestamp: new Date().toISOString(),
  env: process.env.NODE_ENV
});

} catch (error) {
console.error('Error:', error);
response.status(500).send({error: 'Internal Server Error'});
}
};
3.2 鸿蒙端调用云函数
// HarmonyOS云函数调用封装
import agconnect from '@agconnect/api-harmony';
import '@agconnect/function-harmony';

export default class CloudFunction {
static async callFunction(name: string, data?: any): Promise {
try {
const functionCallable = agconnect.function().wrap(name);
const result = await functionCallable.call(data);
return result.getValue();
} catch (error) {
console.error(调用云函数${name}失败:, error);
throw error;
}
}
}

// 使用示例
const response = await CloudFunction.callFunction('hello-world', { name: 'HarmonyOS' });
console.log('云函数响应:', response);
四、复杂业务逻辑实现
4.1 用户认证集成
// functions/user-profile/index.js
const cloud = require('@agconnect/cloud-function');
const auth = require('@agconnect/auth-server');

exports.handler = async (request, response) => {
try {
// 验证用户令牌
const token = request.headers['authorization'];
if (!token) {
return response.status(401).send({error: 'Unauthorized'});
}

const authClient = auth.defaultInstance();
const user = await authClient.verifyToken(token.replace('Bearer ', ''));

// 获取用户资料
const db = cloud.database().database();
const userDoc = await db.collection('users').doc(user.uid).get();

if (!userDoc.exists) {
  return response.status(404).send({error: 'User not found'});
}

// 返回脱敏数据
const userData = userDoc.data();
delete userData.password;
delete userData.sensitiveInfo;

response.status(200).send({
  user: userData,
  privileges: await getUserPrivileges(user.uid)
});

} catch (error) {
console.error('Error:', error);
response.status(500).send({error: error.message});
}
};

async function getUserPrivileges(uid) {
// 复杂权限计算逻辑
const [roles, purchases, subscriptions] = await Promise.all([
getRoles(uid),
getPurchases(uid),
getSubscriptions(uid)
]);

return {
isVIP: subscriptions.some(sub => sub.active),
hasPremiumContent: purchases.some(p => p.type === 'premium'),
adminLevel: roles.includes('admin') ? 2 : roles.includes('moderator') ? 1 : 0
};
}
4.2 数据库事务处理
// functions/process-order/index.js
const cloud = require('@agconnect/cloud-function');

exports.handler = async (request, response) => {
const db = cloud.database().database();
const batch = db.batch();
const { userId, items, paymentInfo } = request.body;

try {
// 1. 验证库存
const inventoryChecks = items.map(item =>
db.collection('inventory').doc(item.sku).get()
);

const inventoryDocs = await Promise.all(inventoryChecks);
const outOfStock = inventoryDocs.filter((doc, i) => 
  !doc.exists || doc.data().quantity < items[i].quantity
);

if (outOfStock.length > 0) {
  return response.status(400).send({
    error: 'Out of stock',
    items: outOfStock.map(doc => doc.id)
  });
}

// 2. 创建订单
const orderRef = db.collection('orders').doc();
batch.set(orderRef, {
  userId,
  items,
  total: calculateTotal(items),
  status: 'processing',
  createdAt: new Date(),
  paymentInfo
});

// 3. 更新库存
items.forEach((item, i) => {
  const inventoryRef = db.collection('inventory').doc(item.sku);
  batch.update(inventoryRef, {
    quantity: inventoryDocs[i].data().quantity - item.quantity,
    lastUpdated: new Date()
  });
});

// 4. 更新用户统计
const userStatsRef = db.collection('userStats').doc(userId);
batch.update(userStatsRef, {
  orderCount: cloud.database().increment(1),
  totalSpent: cloud.database().increment(calculateTotal(items)),
  lastOrderAt: new Date()
}, { merge: true });

// 执行事务
await batch.commit();

// 5. 异步处理后续逻辑
await processPostOrderTasks(orderRef.id, userId);

response.status(201).send({
  orderId: orderRef.id,
  status: 'success'
});

} catch (error) {
console.error('订单处理失败:', error);
response.status(500).send({error: 'Order processing failed'});
}
};

async function processPostOrderTasks(orderId, userId) {
// 异步发送通知、更新推荐系统等
}
五、高级功能实现
5.1 定时触发器

functions/scheduled-tasks/agc.yaml

functions:

  • name: scheduled-tasks
    handler: index.handler
    memorySize: 256
    timeout: 60
    triggers:
    • name: dailyReport
      type: timer
      config: '0 0 2 * * *' # 每天凌晨2点执行
      // functions/scheduled-tasks/index.js
      const cloud = require('@agconnect/cloud-function');
      const admin = require('@agconnect/admin');

exports.handler = async () => {
const db = admin.database();
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);

// 1. 生成每日统计
const [newUsers, orders, revenue] = await Promise.all([
getDailyCount(db, 'users', yesterday),
getDailyCount(db, 'orders', yesterday),
getDailyRevenue(db, yesterday)
]);

// 2. 保存统计结果
await db.collection('dailyReports').doc().set({
date: yesterday.toISOString().split('T')[0],
newUsers,
orders,
revenue,
generatedAt: new Date()
});

// 3. 发送管理员通知
await sendAdminNotification({
title: '每日报告已生成',
content: 昨日新增用户: ${newUsers}, 订单数: ${orders}, 收入: ${revenue}
});

console.log('每日报告生成完成');
};
5.2 云函数间调用
// functions/order-processing/index.js
const cloud = require('@agconnect/cloud-function');

exports.handler = async (request, response) => {
try {
// 调用支付云函数
const paymentResult = await cloud.callFunction({
name: 'process-payment',
data: request.body.payment
});

if (!paymentResult.success) {
  return response.status(400).send(paymentResult);
}

// 调用库存云函数
const inventoryResult = await cloud.callFunction({
  name: 'update-inventory',
  data: {
    items: request.body.items,
    action: 'decrement'
  }
});

// 创建订单记录
const orderResult = await createOrderRecord(request.body);

response.status(201).send({
  payment: paymentResult,
  inventory: inventoryResult,
  order: orderResult
});

} catch (error) {
console.error('订单处理失败:', error);

// 尝试回滚
if (request.body.payment) {
  await cloud.callFunction({
    name: 'reverse-payment',
    data: { transactionId: request.body.payment.transactionId }
  });
}

response.status(500).send({error: 'Order processing failed'});

}
};
六、性能优化实践
6.1 冷启动优化
// functions/optimized-function/index.js
const cloud = require('@agconnect/cloud-function');
const heavyLibrary = require('heavy-library');
let cachedData;

// 初始化耗时操作
async function initialize() {
if (!cachedData) {
cachedData = await heavyLibrary.loadData();
}
return cachedData;
}

// 预热处理
exports.warmup = async () => {
await initialize();
return { status: 'warmed up' };
};

exports.handler = async (request, response) => {
try {
const data = await initialize();
const result = heavyLibrary.process(data, request.body);

response.status(200).send(result);

} catch (error) {
response.status(500).send({error: error.message});
}
};
6.2 内存管理
// functions/memory-intensive/index.js
const cloud = require('@agconnect/cloud-function');
const stream = require('stream');
const util = require('util');

exports.handler = async (request, response) => {
try {
// 使用流处理大数据
const pipeline = util.promisify(stream.pipeline);
const transformStream = createTransformStream();

await pipeline(
  getLargeDataStream(request.query),
  transformStream,
  response.stream()
);

} catch (error) {
console.error('处理失败:', error);
if (!response.headersSent) {
response.status(500).send({error: 'Processing failed'});
}
}
};

function createTransformStream() {
return new stream.Transform({
objectMode: true,
transform(chunk, encoding, callback) {
// 逐条处理数据,避免内存溢出
const processed = processChunk(chunk);
this.push(processed);
callback();
}
});
}
七、安全最佳实践
7.1 输入验证
// functions/secure-endpoint/index.js
const cloud = require('@agconnect/cloud-function');
const Joi = require('joi');

const schema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().pattern(new RegExp('[1]{8,30}$')),
repeat_password: Joi.ref('password'),
age: Joi.number().integer().min(18).max(120),
creditCard: Joi.string().creditCard()
}).with('password', 'repeat_password');

exports.handler = async (request, response) => {
try {
// 验证输入
const { error, value } = schema.validate(request.body);
if (error) {
return response.status(400).send({
error: 'Validation failed',
details: error.details
});
}

// 安全处理
const result = await processSecureData(value);

response.status(200).send(result);

} catch (error) {
console.error('安全处理失败:', error);
response.status(500).send({error: 'Internal server error'});
}
};
7.2 敏感数据处理
// functions/secure-data/index.js
const cloud = require('@agconnect/cloud-function');
const crypto = require('crypto');

// 初始化加密密钥(从环境变量获取)
const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY;
const IV_LENGTH = 16;

exports.handler = async (request, response) => {
try {
// 解密传入数据
const decryptedData = decrypt(request.body.encryptedData);

// 业务处理
const result = await processBusinessLogic(decryptedData);

// 加密返回数据
response.status(200).send({
  encryptedResult: encrypt(JSON.stringify(result))
});

} catch (error) {
console.error('安全数据处理失败:', error);
response.status(500).send({error: 'Secure processing failed'});
}
};

function encrypt(text) {
const iv = crypto.randomBytes(IV_LENGTH);
const cipher = crypto.createCipheriv('aes-256-cbc',
Buffer.from(ENCRYPTION_KEY), iv);

let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return iv.toString('hex') + ':' + encrypted.toString('hex');
}

function decrypt(text) {
const parts = text.split('😂;
const iv = Buffer.from(parts.shift(), 'hex');
const encryptedText = Buffer.from(parts.join('😂, 'hex');

const decipher = crypto.createDecipheriv('aes-256-cbc',
Buffer.from(ENCRYPTION_KEY), iv);

let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}
八、调试与监控
8.1 本地调试配置

agc-local-config.yaml

functions:
hello-world:
runtime: nodejs14
memory: 256MB
timeout: 60s
environment:
NODE_ENV: development
DEBUG: 'true'
variables:
API_KEY: 'local-dev-key'

启动本地调试

agc cloud functions serve

调用测试

curl "http://localhost:8000/hello-world?name=Developer"
8.2 日志与监控集成
// functions/logging-example/index.js
const cloud = require('@agconnect/cloud-function');
const { Logging } = require('@agconnect/logging');

exports.handler = async (request, response) => {
const logger = Logging.getLogger();

try {
logger.info('请求开始', { headers: request.headers });

// 业务逻辑
const result = await processRequest(request.body);

// 结构化日志
logger.info('请求处理成功', {
  resultSize: result.length,
  processingTime: `${Date.now() - startTime}ms`
});

response.status(200).send(result);

} catch (error) {
// 错误日志
logger.error('请求处理失败', {
error: error.message,
stack: error.stack,
input: request.body
});

response.status(500).send({error: error.message});

}
};
九、常见问题解决
​​云函数超时​​:
// 优化长时间运行的任务
exports.handler = async (request, response) => {
// 立即响应,后台继续处理
response.status(202).send({status: 'Processing started'});

// 分阶段处理
await processInBackground(request.body);
};
​​冷启动延迟​​:

agc.yaml 配置

functions:

  • name: my-function
    handler: index.handler
    memorySize: 512 # 增加内存
    timeout: 30
    warmup: true # 启用预热
    ​​依赖管理​​:

精简node_modules

npm install --production

或使用webpack打包

​​跨域问题​​:
// 添加CORS头
response.header('Access-Control-Allow-Origin', '*');
response.header('Access-Control-Allow-Methods', 'GET,POST');
结语
通过AGC云函数,您的鸿蒙5应用可以实现:

​​复杂业务逻辑​​:将计算密集型任务移至云端
​​弹性扩展​​:自动应对用户量增长
​​安全可靠​​:利用华为云基础设施保障数据安全
​​快速迭代​​:独立于客户端发布更新
建议在实际项目中:

合理划分云函数职责(单一职责原则)
实现完善的错误处理和日志记录
建立自动化测试和部署流程
监控性能指标并持续优化


  1. a-zA-Z0-9 ↩︎

posted @ 2025-06-28 22:48  暗雨YA  阅读(54)  评论(0)    收藏  举报