
# 开发Node.js事件函数
Node.js的事件函数开发，支持本地开发后上传代码文件，也支持直接在FunctionGraph控制台创建函数在线编辑代码。
关于Node.js函数的接口定义以及SDK接口说明请参考[Node.js函数开发概述](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0501.html)。
#### 约束与限制
- callback返回的第一个参数不为null，则认为函数执行失败，会返回定义在第二个参数的HTTP错误信息。
- 当使用APIG触发器时，函数返回必须使用示例中output的格式， 函数Body参数仅支持返回如下几种类型的值。
  - null：函数返回的HTTP响应Body为空。
  
  - \[\]byte: 函数返回的HTTP响应Body内容为该字节数组内容。
  
  - string：函数返回的HTTP响应Body内容为该字符串内容。
   
- 通过APIG服务调用函数服务时，isBase64Encoded的值默认为true，表示APIG传递给FunctionGraph的请求体body已经进行Base64编码，需要先对body内容Base64解码后再处理。
  函数必须按以下结构返回字符串。
  ```
  {
      "isBase64Encoded": true|false,
      "statusCode": httpStatusCode,
      "headers": {"headerName":"headerValue",...},
      "body": "..."
  }
  ```
  
 
 #### 步骤一：创建Node.js函数工程
1. 打开本地文本编辑器，编写函数代码，将文件命名为"index.js"。
   - 以下代码为同步形式入口函数：
     ```
     exports.handler = function (event, context, callback) {
         const error = null;
         const output = {
             'statusCode': 200,
             'headers':
             {
                 'Content-Type': 'application/json'
             },
             'isBase64Encoded': false,
             'body': JSON.stringify(event),
         }
         callback(error, output);
     }
     ```
     
   
   - 以下代码为异步形式入口函数，运行时 8.10 及以上支持：
     ```
     exports.handler = async (event, context) => {
         const output =
         {
             'statusCode': 200,
             'headers':
             {
                 'Content-Type': 'application/json'
             },
             'isBase64Encoded': false,
             'body': JSON.stringify(event),
         }
         return output;
     }
     ```
     如果您的Node.js函数中包含异步任务，需使用Promise以确保该异步任务在当次调用执行，可以直接在return中声明Promise，也可以await执行该Promise。
     暂时不支持在函数响应请求后继续执行异步任务的能力。
     ```
     exports.handler =  async(event, context ) => {
         const output =
         {
             'statusCode': 200,
             'headers':
             {
                 'Content-Type': 'application/json'
             },
             'isBase64Encoded': false,
             'body': JSON.stringify(event),
         }
      
         const promise = new Promise((resolve, reject) => {
             setTimeout(() => {
                 resolve(output)
             }, 2000)
         })
         return promise;
         // another way 
         // res = await promise;
         // return res;
     }
     ```
     **异步执行函数** **说明：**
     如果期望函数先响应，随后继续执行任务，即异步执行函数，可以通过SDK/API调用FunctionGraph的[异步执行函数](https://support.huaweicloud.com/api-functiongraph/functiongraph_06_0126.html)接口实现。
     如需使用APIG触发器，可以单击生成的APIG触发器名称，跳转到APIG服务页面，选择Asynchronous（异步）方式调用，具体操作步骤可参考[配置函数的异步调用](https://support.huaweicloud.com/usermanual-functiongraph/functiongraph_01_0160.html#section2)。
     
    
2. 打包函数工程。以使用异步形式入口为例。 函数工程创建以后，会得到以下目录，选中工程所有文件，打包成Zip文件并命名为"fss_examples_nodejs.zip"。打包时请确保解压后，入口函数所在的文件位于根目录。
   您也可以直接下载打包好的[Node.js函数样例工程包](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0101.html#functiongraph_02_0101__section3825924414326)使用。
   图1打包   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002369539909.png "点击放大") 
 
#### 步骤二：创建FunctionGraph函数
1. 登录[函数工作流控制台](https://console.huaweicloud.com/functiongraph/?locale=zh-cn)，右上角单击"创建函数"。
2. 如[图2]所示，创建一个空白的Node.js事件函数，单击"立即创建"进入函数详情页。
   图2创建Node.js函数   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002332902358.png "点击放大")
   
   
3. 如[图3]所示，单击"上传代码 \> Zip文件"，上传[步骤一：创建Node.js函数工程]打包的fss_examples_nodejs.zip文件。
   上传的代码将在函数工作流控制台自动部署，如修改代码，请再次单击"部署代码"。
   图3上传程序包   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002333071214.png "点击放大")
   
   
![](https://support.huaweicloud.com/devg-functiongraph/public_sys-resources/note_3.0-zh-cn.png)
**修改函数执行入口：**
在FunctionGraph控制台左侧导航栏选择"函数 \> 函数列表"，单击需要设置的"函数名称"进入函数详情页，选择"设置 \> 常规设置"，配置"函数执行入口"参数，如[图4]所示。
图4函数执行入口参数   
![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002335621790.png "点击放大")
- 函数执行入口中的index：与[步骤一：创建Node.js函数工程]中创建的函数文件名保持一致，通过该名称找到FunctionGraph函数所在文件。
- 函数执行入口中的handler：为执行函数名，与[步骤一：创建Node.js函数工程]中创建的index.js文件代码中的函数名保持一致。
 
#### 步骤三：测试函数
1. 在"代码"页签下，单击"测试"，弹出"配置测试事件"弹窗，如[图5]所示配置测试事件"test"，单击"创建"。
   图5配置测试事件   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002394514509.png "点击放大") 
2. 选择已配置的测试事件"test"，单击"测试"。
3. 如[图6]所示，右侧出现"执行结果"窗口，可测试函数是否执行成功。
   图6测试结果   
   ![](https://support.huaweicloud.com/devg-functiongraph/zh-cn_image_0000002366925253.png "点击放大")
   
   
 
#### 函数执行结果说明
函数执行结果由3部分组成：函数返回、执行摘要和日志。
表1执行结果说明 
| 参数项  | 执行成功                          | 执行失败                                                                                                                                                                                               |
|:---|:---|:---|
| 函数返回 | 返回函数中定义的返回信息。                 | 返回包含错误信息和错误类型的JSON文件。格式如下： ``` { "errorMessage": "", "errorType":"", } ``` errorMessage：Runtime返回的错误信息 errorType：错误类型 |
| 执行摘要 | 显示请求ID、配置内存、执行时长、实际使用内存和收费时长。 | 显示请求ID、配置内存、执行时长、实际使用内存和收费时长。                                                                                                                                                                      |
| 日志   | 打印函数日志，最多显示4KB的日志。            | 打印报错信息，最多显示4KB的日志。                                                                                                                                                                                 |
   
#### 相关文档
- 使用Node.js运行时语言开发HTTP函数，可参考[使用Node.js开发HTTP函数](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0611.html)。
- 制作Node.js运行时的函数依赖包，可参考[为Node.js函数制作依赖包](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0612.html)。
- 关于函数开发的更多说明，如函数支持的运行时、函数支持的触发事件、函数工程打包规范以及如何在函数中引入动态链接库，请参见[函数开发概述](https://support.huaweicloud.com/devg-functiongraph/functiongraph_02_0100.html)。
 
