fn
├── README.md
├── func.yaml (1)
├── go.mod (2)
├── go.sum
├── handle.go
└── handle_test.go
OpenShift Serverless Functions with Go 仅为技术预览功能。技术预览功能不受 Red Hat 生产服务级别协议 (SLA) 的支持,并且可能功能不完整。Red Hat 不建议在生产环境中使用它们。这些功能可让客户尽早访问即将推出的产品功能,从而能够在开发过程中测试功能并提供反馈。 有关 Red Hat 技术预览功能的支持范围的更多信息,请参见 技术预览功能支持范围。 |
在您创建 Go 函数项目后,您可以修改提供的模板文件以向您的函数添加业务逻辑。这包括配置函数调用以及返回的标头和状态代码。
在开发函数之前,您必须完成配置 OpenShift Serverless Functions中的步骤。
使用 Knative (kn
) CLI 创建 Go 函数时,项目目录看起来像一个典型的 Go 项目。唯一的例外是额外的func.yaml
配置文件,用于指定镜像。
Go 函数的限制很少。唯一的要求是您的项目必须在function
模块中定义,并且必须导出函数Handle()
。
http
和event
触发函数具有相同的模板结构。
fn
├── README.md
├── func.yaml (1)
├── go.mod (2)
├── go.sum
├── handle.go
└── handle_test.go
1 | func.yaml 配置文件用于确定镜像名称和注册表。 |
2 | 您可以向go.mod 文件添加任何所需的依赖项,其中可以包含其他本地 Go 文件。构建项目以进行部署时,这些依赖项将包含在生成的运行时容器镜像中。添加依赖项的示例
|
使用 Knative (kn
) CLI 创建函数项目时,您可以生成一个响应 CloudEvents 的项目,或者生成一个响应简单 HTTP 请求的项目。Go 函数的调用方法不同,具体取决于它们是由 HTTP 请求还是 CloudEvent 触发。
当收到传入的 HTTP 请求时,函数会以标准 Go Context 作为第一个参数调用,后跟 http.ResponseWriter
和 http.Request
参数。您可以使用标准 Go 技术访问请求,并为您的函数设置相应的 HTTP 响应。
func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
// Read body
body, err := ioutil.ReadAll(req.Body)
defer req.Body.Close()
if err != nil {
http.Error(res, err.Error(), 500)
return
}
// Process body and function logic
// ...
}
当收到传入的云事件时,该事件将由 CloudEvents Go SDK 调用。调用使用 Event
类型作为参数。
您可以利用 Go Context 作为函数契约中的可选参数,如支持的函数签名列表所示。
Handle()
Handle() error
Handle(context.Context)
Handle(context.Context) error
Handle(cloudevents.Event)
Handle(cloudevents.Event) error
Handle(context.Context, cloudevents.Event)
Handle(context.Context, cloudevents.Event) error
Handle(cloudevents.Event) *cloudevents.Event
Handle(cloudevents.Event) (*cloudevents.Event, error)
Handle(context.Context, cloudevents.Event) *cloudevents.Event
Handle(context.Context, cloudevents.Event) (*cloudevents.Event, error)
收到一个云事件,该事件在 data 属性中包含一个 JSON 字符串。
{
"customerId": "0123456",
"productId": "6543210"
}
要访问此数据,必须定义一个结构体,该结构体映射云事件数据中的属性,并从传入的事件中检索数据。以下示例使用 Purchase
结构体。
type Purchase struct {
CustomerId string `json:"customerId"`
ProductId string `json:"productId"`
}
func Handle(ctx context.Context, event cloudevents.Event) (err error) {
purchase := &Purchase{}
if err = event.DataAs(purchase); err != nil {
fmt.Fprintf(os.Stderr, "failed to parse incoming CloudEvent %s\n", err)
return
}
// ...
}
或者,可以使用 Go encoding/json
包直接将云事件作为字节数组形式的 JSON 进行访问。
func Handle(ctx context.Context, event cloudevents.Event) {
bytes, err := json.Marshal(event)
// ...
}
由 HTTP 请求触发的函数可以直接设置响应。您可以使用 Go http.ResponseWriter 配置函数来执行此操作。
func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
// Set response
res.Header().Add("Content-Type", "text/plain")
res.Header().Add("Content-Length", "3")
res.WriteHeader(200)
_, err := fmt.Fprintf(res, "OK\n")
if err != nil {
fmt.Fprintf(os.Stderr, "error or response write: %v", err)
}
}
由云事件触发的函数可能返回空值、error
或 CloudEvent
以便将事件推送到 Knative Eventing 系统。在这种情况下,必须为云事件设置唯一的 ID
、正确的 Source
和 Type
。数据可以从定义的结构体或 map
中填充。
func Handle(ctx context.Context, event cloudevents.Event) (resp *cloudevents.Event, err error) {
// ...
response := cloudevents.NewEvent()
response.SetID("example-uuid-32943bac6fea")
response.SetSource("purchase/getter")
response.SetType("purchase")
// Set the data from Purchase type
response.SetData(cloudevents.ApplicationJSON, Purchase{
CustomerId: custId,
ProductId: prodId,
})
// OR set the data directly from map
response.SetData(cloudevents.ApplicationJSON, map[string]string{"customerId": custId, "productId": prodId})
// Validate the response
resp = &response
if err = resp.Validate(); err != nil {
fmt.Printf("invalid event created. %v", err)
}
return
}