开发Go事件函数
关于Go函数的接口定义以及SDK接口说明请参考Go函数开发概述。
开发Go函数
登录已经安装了Go 1.x SDK的linux服务器,按照如下步骤进行编译和打包。(当前支持Ubuntu 14.04,Ubuntu 16.04,SuSE 11.3,SuSE 12.0,SuSE 12.1)
- 创建一个临时目录例如“/home/fssgo”,将FunctionGraph的Go RUNTIME SDK解压到新创建的目录,并开启go module开关,操作如下:
$ mkdir -p /home/fssgo
$ unzip functiongraph-go-runtime-sdk-1.0.1.zip -d /home/fssgo
$ export GO111MODULE="on"
- 在目录“/home/fssgo”下生成go.mod文件,操作如下,以模块名为test为例:
$ go mod init test
- 在目录“/home/fssgo”下编辑go.mod文件,添加加粗部分内容:
module test go 1.24.5 require ( huaweicloud.com/go-runtime v0.0.0-00010101000000-000000000000 ) replace ( huaweicloud.com/go-runtime => ./go-runtime )
- 在目录“/home/fssgo”下创建函数文件,并实现如下接口:
func Handler(payload []byte, ctx context.RuntimeContext) (interface{}, error)
其中payload为客户端请求的body数据,ctx为FunctionGraph提供的运行时上下文对象,具体提供的方法可以参考表19,以test.go为例:
package main import ( "fmt" "huaweicloud.com/go-runtime/go-api/context" "huaweicloud.com/go-runtime/pkg/runtime" "huaweicloud.com/go-runtime/events/apig" "huaweicloud.com/go-runtime/events/cts" "huaweicloud.com/go-runtime/events/dds" "huaweicloud.com/go-runtime/events/dis" "huaweicloud.com/go-runtime/events/kafka" "huaweicloud.com/go-runtime/events/lts" "huaweicloud.com/go-runtime/events/smn" "huaweicloud.com/go-runtime/events/timer" "encoding/json" ) func ApigTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var apigEvent apig.APIGTriggerEvent err := json.Unmarshal(payload, &apigEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", apigEvent.String()) apigResp := apig.APIGTriggerResponse{ Body: apigEvent.String(), Headers: map[string]string { "content-type": "application/json", }, StatusCode: 200, } return apigResp, nil } func CtsTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var ctsEvent cts.CTSTriggerEvent err := json.Unmarshal(payload, &ctsEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", ctsEvent.String()) return "ok", nil } func DdsTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var ddsEvent dds.DDSTriggerEvent err := json.Unmarshal(payload, &ddsEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", ddsEvent.String()) return "ok", nil } func DisTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var disEvent dis.DISTriggerEvent err := json.Unmarshal(payload, &disEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", disEvent.String()) return "ok", nil } func KafkaTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var kafkaEvent kafka.KAFKATriggerEvent err := json.Unmarshal(payload, &kafkaEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", kafkaEvent.String()) return "ok", nil } func LtsTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var ltsEvent lts.LTSTriggerEvent err := json.Unmarshal(payload, <sEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", ltsEvent.String()) return "ok", nil } func SmnTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var smnEvent smn.SMNTriggerEvent err := json.Unmarshal(payload, &smnEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", smnEvent.String()) return "ok", nil } func TimerTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var timerEvent timer.TimerTriggerEvent err := json.Unmarshal(payload, &timerEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } return timerEvent.String(), nil } func main() { runtime.Register(ApigTest) }
约束与限制:
- 如果函数返回的error参数不是nil,则会认为函数执行失败。
- 如果函数返回的error为nil,FunctionGraph仅支持返回如下几种类型的值。
[]byte:返回的HTTP响应Body内容为该字节数组内容。
string:返回的HTTP响应Body内容为该字符串内容。
其它:FunctionGraph会将返回值作为对象进行json编码,并将编码后的内容作为HTTP响应的Body,同时设置响应的"Content-Type"头为"application/json"。
- 上述例子使用APIG触发器的事件类型,如需使用其他触发器类型需要修改main函数的内容,例如使用CTS触发器则修改为runtime.Register(CtsTest),目前只支持注册一个入口。
- 当函数的事件源是APIG时,相关约束条件请参考Base64解码和返回结构体的说明。
- 编译和打包
函数代码编译完成后,按照如下方式编译和打包。
- 创建函数
登录函数工作流控制台,创建Go1.x函数,上传代码包fss_examples_go1.x.zip。
对于Go runtime,必须在编译之后打zip包,编译后的文件名称必须与函数执行入口的名称保持一致,例如:二进制文件名为handler,则“函数执行入口”命名为handler,Handler与步骤1中定义的函数保持一致。
- 测试函数
- 创建一个临时目录例如“/home/fssgo/src/huaweicloud.com”,将FunctionGraph的sdk Go RUNTIME SDK解压到新创建的目录,操作如下:
$ mkdir -p /home/fssgo/src/huaweicloud.com
$ unzip functiongraph-go-runtime-sdk-1.0.1.zip -d /home/fssgo/src/huaweicloud.com
- 在目录“/home/fssgo/src”下创建函数文件,并实现如下接口:
func Handler(payload []byte, ctx context.RuntimeContext) (interface{}, error)
其中payload为客户端请求的body数据,ctx为FunctionGraph提供的运行时上下文对象,具体提供的方法可以参考SDK接口,以test.go为例:
package main import ( "fmt" "huaweicloud.com/go-runtime/go-api/context" "huaweicloud.com/go-runtime/pkg/runtime" "huaweicloud.com/go-runtime/events/apig" "huaweicloud.com/go-runtime/events/cts" "huaweicloud.com/go-runtime/events/dds" "huaweicloud.com/go-runtime/events/dis" "huaweicloud.com/go-runtime/events/kafka" "huaweicloud.com/go-runtime/events/lts" "huaweicloud.com/go-runtime/events/smn" "huaweicloud.com/go-runtime/events/timer" "encoding/json" ) func ApigTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var apigEvent apig.APIGTriggerEvent err := json.Unmarshal(payload, &apigEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", apigEvent.String()) apigResp := apig.APIGTriggerResponse{ Body: apigEvent.String(), Headers: map[string]string { "content-type": "application/json", }, StatusCode: 200, } return apigResp, nil } func CtsTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var ctsEvent cts.CTSTriggerEvent err := json.Unmarshal(payload, &ctsEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", ctsEvent.String()) return "ok", nil } func DdsTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var ddsEvent dds.DDSTriggerEvent err := json.Unmarshal(payload, &ddsEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", ddsEvent.String()) return "ok", nil } func DisTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var disEvent dis.DISTriggerEvent err := json.Unmarshal(payload, &disEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", disEvent.String()) return "ok", nil } func KafkaTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var kafkaEvent kafka.KAFKATriggerEvent err := json.Unmarshal(payload, &kafkaEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", kafkaEvent.String()) return "ok", nil } func LtsTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var ltsEvent lts.LTSTriggerEvent err := json.Unmarshal(payload, <sEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", ltsEvent.String()) return "ok", nil } func SmnTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var smnEvent smn.SMNTriggerEvent err := json.Unmarshal(payload, &smnEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } ctx.GetLogger().Logf("payload:%s", smnEvent.String()) return "ok", nil } func TimerTest(payload []byte, ctx context.RuntimeContext) (interface{}, error) { var timerEvent timer.TimerTriggerEvent err := json.Unmarshal(payload, &timerEvent) if err != nil { fmt.Println("Unmarshal failed") return "invalid data", err } return timerEvent.String(), nil } func main() { runtime.Register(ApigTest) }
约束与限制:
- 如果函数返回的error参数不是nil,则会认为函数执行失败。
- 如果函数返回的error为nil,FunctionGraph仅支持返回如下几种类型的值。
[]byte:返回的HTTP响应Body内容为该字节数组内容。
string:返回的HTTP响应Body内容为该字符串内容。
其它:FunctionGraph会将返回值作为对象进行json编码,并将编码后的内容作为HTTP响应的Body,同时设置响应的"Content-Type"头为"application/json"。
- 上述例子使用APIG触发器的事件类型,如需使用其他触发器类型需要修改main函数的内容,例如使用CTS触发器则修改为runtime.Register(CtsTest),目前只支持注册一个入口。
- 当函数的事件源是APIG时,相关约束条件请参考Base64解码和返回结构体的说明。
- 编译和打包
函数代码编译完成后,按照如下方式编译和打包。
- 创建函数
登录函数工作流控制台,创建Go1.x函数,上传代码包fss_examples_go1.x.zip。
对于Go runtime,必须在编译之后打zip包,编译后的文件名称必须与函数执行入口的名称保持一致,例如:二进制文件名为handler,则“函数执行入口”命名为handler,Handler与步骤1中定义的函数保持一致。
- 测试函数