HarmonyOS NEXT端云一体化云侧云函数介绍和开发

云函数是一项Serverless计算服务,提供FaaS(Function as a Service)能力,可以类比于服务器端对外提供的API接口,相比于服务器端优势在于开发者只需要聚焦于业务逻辑实现、开发并上传函数代码,通过少量的代码可以实现类似服务器端操作数据库、存储等能力。还可以根据函数的实际使用流量对函数进行弹性伸缩,而无需对服务器资源进行管理,替开发者完全解决了传统应用开发与运维中的诸多复杂事务(如服务器配置与管理、代码部署、负载均衡、弹性伸缩、高可用保证等等)。

DevEco Studio集成开发工具提供端云协同开发能力,在云侧工程创建函数、实现业务逻辑代码、调试函数、部署函数,端侧通过少量的代码调用部署到AGC云端的云函数获取业务数据。云侧工程开发云函数总体流程如下所示:

  • 创建并配置函数:云侧工程中创建函数、为函数配置入口以及调用的触发器等。
  • 开发函数:函数创建并配置完成后,在函数入口文件中编写业务逻辑代码。
  • 调试函数:业务逻辑代码编写完成后,在DevEco Studio中调试函数代码是否运行正常。
  • 部署函数:完成函数代码开发与调试后,开发者可以将函数部署到AGC云端,支持单个部署和批量部署。

1、创建配置云函数

1)创建云函数

展开云侧工程(CloudProgram),右击cloudfunctions目录,选择New > Cloud Function打开创建云函数向导。

在创建云函数向导中输入云函数名称(如calculate-baby-age,该函数用于计算宝宝年龄,包含年、月、日、天数),函数名称长度2-63个字符,仅支持小写英文字母、数字、中划线(-),首字符必须为小写字母,结尾不能为中划线(-)。然后在"Select the Cloud Function Type"栏选择云函数Cloud Function(云对象Cloud Object会在后面的项目中进行介绍),最后点击OK按钮,等待DevEco Studio完成云函数创建。

DevEco Studio完成云函数创建后,会在cloudfunctions目录新建get-due-date函数目录,并创建函数配置文件function-config.json、函数入口文件myCloudFunction.ts以及依赖配置文件package.json

2)配置云函数

在云函数配置文件中,我们只需要关注配置触发器属性triggers,通过触发器暴露的触发条件来实现函数调用。而函数入口属性handler和函数类型functionType默认即可,特别需要注意的是functionType的值在创建时根据开发者选择的"Select the Cloud Function Type"类型自动生成,"0"表示云函数,"1"表示云对象,不可手动修改,否则会导致云函数部署失败。

DevEco Studio云侧工程云函数当前仅支持HTTP触发器,云函数创建成功后,会在云函数配置文件function-config.json文件中自动完成HTTP触发器配置。函数部署到云端后会自动生成触发器URL,开发者向URL发起HTTP请求时触发函数。

json 复制代码
{
  "handler": "calculateBabyAge.myHandler",
  "functionType": 0,
  "triggers": [
    {
      "type": "http",
      "properties": {
        "enableUrlDecode": true,
        "authFlag": "true",
        "authAlgor": "HDA-SYSTEM",
        "authType": "apigw-client"
      }
    }
  ]
}
  • type:触发器类型,端云协同工具中仅支持配置为http

  • properties:触发器属性。

    • enableUrlDecode:通过HTTP触发器触发函数时,对于contentTypeapplication/x-www-form-urlencoded的触发器请求,是否使用URLDecoder对请求body进行解码再转发到函数中。true表示启用;false表示不启用。

    • authFlag:是否鉴权,默认为true

    • authAlgor:鉴权算法,默认为HDA-SYSTEM

    • authType:HTTP触发器的认证类型。

      • apigw-client:端侧网关认证,适用于来自APP客户端侧(即本地应用或者项目)的函数调用。
      • cloudgw-client:云侧网关认证,适用于来自APP服务器侧(即云函数)的函数调用。

2、开发云函数

云函数创建和配置完成后,接下来可以编写函数业务逻辑代码。打开函数入口文件getDueDate.ts,在入口方法myHandler中编写业务逻辑代码,不建议重命名方法名称。

csharp 复制代码
let myHandler = async function (event, context, callback, logger) {
  logger.info(event);
​
  // do something here
​
  callback({
    code: 0,
    desc: "Success."
  });
};
​
export { myHandler };
  • myHandler:入口方法名称。

  • event:调用方法传递的事件对象,JSON格式。采用触发器的方式实现函数调用,函数入口方法需要遵循对应触发器的event对象字段要求。本项目使用HTTP触发器,event对象数据格式如下所示:

    • path:HTTP请求触发URL路径。
    • httpMethod:触发器请求方式,目前HTTP触发器仅支持POST事件请求方式。
    • headers:请求头,指明请求或描述消息,一般包含"authorization"、"content-length"、"x-tenant-id"、"x-business-id"、"x-product-id"、"content-type"、"connection"、"accept-encoding"等字段,开发者可自定义。
    • queryStringParameters:请求数据的消息体,可由您自定义,JSON格式的字符串,最大为4MB。如果函数由应用客户端调用,在函数定义中需要在event.body获取用户客户端传入的HTTP body体,再从body体中解析传入的参数值。
    • isBase64Encoded:消息体是否为base64编码的布尔值标识。true:消息体为base64编码;false:消息体非base64编码。
  • context:函数运行时上下文对象,封装了日志接口、回调接口、环境变量env对象等。

  • callback:事件处理结果。函数必须通过显式调用callback(object)将事件处理结果返回给AGC,结果可以是任意对象,但必须与JSON.stringify兼容,AGC会将结果转换成JSON字符串,返回给调用方。callback执行完成,即函数执行结束。

  • logger:代码中可以使用logger接口记录日志,目前支持四种级别:

    • logger.debug()
    • logger.error()
    • logger.warn()
    • logger.info()
typescript 复制代码
let myHandler = async function (event, context, callback, logger) {
  logger.info(event);
​
  // 获取端侧传递的参数
  let birthday = event.body?JSON.parse(event.body).birthday : event.birthday;
  
  try {
    // 计算宝宝的年龄
    const babyAge = calculateBabyAge(birthday);
    // 返回结果
    callback({
      code: 200,
      desc: "Success.",
      data: babyAge
    })
  } catch (error) {
    // 返回结果
    callback({
      code: 0,
      desc: error
    });
  }
};
​
export { myHandler };
​
/**
 * 表示宝宝年龄的类
 */
class BabyAge {
  years: number;
  months: number;
  days: number;
  totalDays: number;
​
  /**
   * @param {number} years - 年数
   * @param {number} months - 月数
   * @param {number} days - 天数
   * @param {number} totalDays - 总天数
   */
  constructor(years, months, days, totalDays) {
    this.years = years;
    this.months = months;
    this.days = days;
    this.totalDays = totalDays;
  }
​
  /**
   * 获取格式化的年龄字符串
   * @returns {string} 格式化的年龄字符串
   */
  toString() {
    return `${this.years}岁${this.months}个月${this.days}天`;
  }
​
  /**
   * 获取总天数的描述
   * @returns {string} 总天数的描述
   */
  getTotalDaysString() {
    return `总共${this.totalDays}天`;
  }
​
  /**
   * 获取完整的年龄描述
   * @returns {string} 完整的年龄描述
   */
  getFullDescription() {
    return `${this.toString()}(${this.getTotalDaysString()})`;
  }
​
  /**
   * 转换为JSON对象
   * @returns {Object} 包含年龄信息的对象
   */
  toJSON() {
    return {
      years: this.years,
      months: this.months,
      days: this.days,
      totalDays: this.totalDays
    };
  }
}
​
/**
 * 计算宝宝从出生到现在的详细年龄信息
 * @param {string} birthDate - 宝宝出生日期,格式:YYYY-MM-DD
 * @returns {BabyAge} 包含年、月、天的BabyAge实例
 */
function calculateBabyAge(birthDate) {
  // 将生日字符串转换为Date对象
  const birth = new Date(birthDate);
  const today = new Date();
​
  // 确保输入的日期格式正确
  if (isNaN(birth.getTime())) {
    throw new Error('请输入正确的日期格式:YYYY-MM-DD');
  }
​
  // 检查生日是否在将来
  if (birth > today) {
    throw new Error('出生日期不能在将来');
  }
​
  // 计算年份差异
  let years = today.getFullYear() - birth.getFullYear();
  let months = today.getMonth() - birth.getMonth();
  let days = today.getDate() - birth.getDate();
​
  // 处理月份为负数的情况
  if (days < 0) {
    months--;
    // 获取上个月的最后一天
    const lastMonth = new Date(today.getFullYear(), today.getMonth(), 0);
    days += lastMonth.getDate();
  }
​
  // 处理月份为负数的情况
  if (months < 0) {
    years--;
    months += 12;
  }
​
  // 计算总天数
  const totalDays = Math.floor((today.getTime() - birth.getTime()) / (1000 * 60 * 60 * 24));
​
  // 返回BabyAge实例
  return new BabyAge(years, months, days, totalDays);
}
相关推荐
小赵学鸿蒙24 分钟前
用Uniapp开发鸿蒙项目 五
前端
小lan猫26 分钟前
【实战】 Vue 3、Anything LLM + DeepSeek本地化项目(五)
前端·vue.js
星使bling27 分钟前
基于Baidu JSAPI Three的卫星轨道三维可视化Demo
前端·javascript
Oder_C28 分钟前
自定义指令-优化v-if和v-show上的使用
前端·javascript·vue.js
小赵学鸿蒙29 分钟前
用Uniapp开发鸿蒙项目 八(上)
前端
拾光拾趣录30 分钟前
TypeScript 数组与对象类型定义
前端
小赵学鸿蒙31 分钟前
用Uniapp开发鸿蒙项目 四
前端
程序猿阿伟1 小时前
《深入解析:如何通过CSS集成WebGPU实现高级图形效果》
前端·css
Monster411 小时前
鸿蒙性能引擎:ArkCompiler实战精要
前端
ze_juejin1 小时前
Typescript中的继承示例
前端·typescript