You need to enable JavaScript to run this app.
导航

开发方法

最近更新时间2023.03.02 20:24:19

首次发布时间2022.04.15 14:52:34

对于 Golang 函数,veFaaS 提供了一套 Runtime SDK 供您编写函数服务。您需要将该 Runtime SDK 导入您的本地代码。veFaaS 会使用该 Runtime SDK 暴露的入口函数启动函数服务进程,对 HTTP 请求或者 Event 事件进行处理。

启动函数

目前,veFaaS 提供两种函数启动入口:Start(handler interface{})StartWithInitializer(handler interface{}, initializer interface{}),请根据实际需要选择合适的启动函数。

Start 函数

一般场景下,您可以选择 Start 函数作为启动函数。
您需要向该函数提供一个 handler 函数作为入参。handler 函数用于处理具体的业务逻辑,handler 函数的具体介绍请参考 handler 函数
使用 Start 函数作为启动函数的 Golang 代码示例如下。

package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/volcengine/vefaas-golang-runtime/events"
    "github.com/volcengine/vefaas-golang-runtime/vefaas"
    "github.com/volcengine/vefaas-golang-runtime/vefaascontext"
)

func main() {
    // Start your vefaas function.
    vefaas.Start(handler)
}

// Define your handler function.
func handler(ctx context.Context, r *events.HTTPRequest) (*events.EventResponse, error) {
    fmt.Printf("request id: %v", vefaascontext.RequestIdFromContext(ctx))
    fmt.Printf("request headers: %v", r.Headers)

    body, _ := json.Marshal(map[string]string{"message": "Hello veFaaS!"})
    return &events.EventResponse{
        Headers: map[string]string{
            "Content-Type": "application/json",
        },
        Body: body,
    }, nil
}

StartWithInitializer 函数

如果函数有一些全局的初始化逻辑,如加载配置文件、与数据库建立连接、初始化下游 Client 等,推荐使用 StartWithInitializer 函数作为启动函数。
您需要向该函数提供两个入参。

  • handler 函数:用于处理具体业务逻辑,handler 函数的具体介绍请参考 handler 函数

  • initializer 函数:用于函数实例初始化,initializer 函数的具体介绍请参考 initializer 函数

使用 StartWithInitializer 函数作为启动函数的 Golang 代码示例如下。

package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/volcengine/vefaas-golang-runtime/events"
    "github.com/volcengine/vefaas-golang-runtime/vefaas"
    "github.com/volcengine/vefaas-golang-runtime/vefaascontext"
)

func main() {
    // Start your vefaas function.
    vefaas.StartWithInitializer(handler, initializer)
}

// Define your handler function.
func handler(ctx context.Context, r *events.HTTPRequest) (*events.EventResponse, error) {
    fmt.Printf("request id: %v", vefaascontext.RequestIdFromContext(ctx))
    fmt.Printf("request headers: %v", r.Headers)

    body, _ := json.Marshal(map[string]string{"message": "Hello veFaaS!"})
    return &events.EventResponse{
        Headers: map[string]string{
            "Content-Type": "application/json",
        },
        Body: body,
    }, nil
}

func initializer(ctx context.Context) error {
    // Do the initialization stuff, e.g., setup database connection,
    // http client for the downstream, or others, which may involve the declaration
    // and initialization of some global variables.
    //
    // Return error (recommended) or just panic (veFaaS will help recover) here if
    // something wrong happened.

    return nil
}

handler 函数

handler 是函数请求处理逻辑的入口。handler 包含了用户的核心业务逻辑,用于接收 HTTP 类型或 Event 类型的请求,进行处理,并最终返回 Response。
根据接收的请求类型,handler 函数签名可以分为以下 3 种,请根据实际需要采用合适的签名。

处理常规 HTTP 请求

该类型函数签名如下所示,接收 HTTP Request 以及对应的 Context,返回 EventResponse 以及请求处理过程中可能的 Error。适用于通过 API 网关触发器请求 veFaaS 函数的场景。

// Handle regular HTTP request.
func(context.Context, *events.HTTPRequest) (*events.EventResponse, error)

参数说明

参数说明

context.Context

表示运行时的信息,包含请求的超时、Request ID 等。具体详见 vefaas-golang-runtime/vefaascontext/context.go
Request ID 是 veFaaS 为每个请求生成的 uuid,可以通过上述代码样例中的vefaascontext.RequestIdFromContext函数从 Context 中提取。

events.HTTPRequest表示经 veFaaS 封装后的 HTTP Request,包含了处理 HTTP 请求所需的元信息,如请求方法、Header 信息以及请求 Payload 等。具体数据结构定义详见 vefaas-golang-runtime/events/http.go
events.EventResponse用于函数返回请求执行的结果,如状态码、Header 信息以及 Payload。具体数据结构定义详见 vefaas-golang-runtime/events/response.go

error

提供了一种错误处理的简便方式。
如果 handler 返回 non-nil 的 error,最终返回的 Response 信息中, 状态码会被设置为 500,该 error 信息会被封装在 Response 的 Header 信息中(可以通过X-Faas-Response-Error-Message Header 提取),此时用户 handler 返回的events.EventResponse将会做忽略处理。

注意

events.EventResponseerror不可同时为 nil 值。

处理 CloudEvent 请求

该类型签名如下所示,接收一个经 veFaaS 封装的 CloudEvent 格式请求以及对应的 Context,返回 EventResponse 以及请求处理过程中可能的 Error。适用于处理 Timer 触发器、Kafka 触发器等事件类型的触发场景。

// Handle CloudEvent request.
func(context.Context, *events.CloudEvent) (*events.EventResponse, error)

参数说明

  • context.Contextevents.EventResponseerror 参数说明与处理常规 HTTP 请求的handler 函数相同。

  • 其余参数说明请参见下表。

参数说明
events.CloudEvent表示经 veFaaS 简单封装后的 CloudEvent 类型的 Event,包含了事件的 Context 信息、Payload 是否 base64 编码以及具体的 Payload。具体数据结构定义详见 vefaas-golang-runtime/events/cloudevent.go

处理任意类型的请求

该类型签名如下所示,适用于一个函数要同时接收常规的 HTTP 请求以及事件类型请求的场景。您可在 handler 函数内部,通过 Golang 的类型断言,进一步区分请求类型,并针对性地处理。

// Handle request of any type.
func(context.Context, interface{}) (*events.EventResponse, error)

参数说明

  • context.Contextevents.EventResponseerror参数说明与处理常规 HTTP 请求的 handler 函数相同。

  • 对于 interface{} 类型 payload 处理示例如下。

func handler(ctx context.Context, payload interface{}) (*events.EventResponse, error) {
    switch event := payload.(type) {
    case *events.HTTPRequest:
        fmt.Printf("received http request, %v", event)
        // Handle regular HTTP request.
        return &events.EventResponse{StatusCode: http.StatusOK}, nil
    case *events.CloudEvent:
        fmt.Printf("received CloudEvent request, %v", event)
        // Handle CloudEvent request.
        return &events.EventResponse{StatusCode: http.StatusOK}, nil
    default:
        errMsg := fmt.Sprintf("unexpected payload type %T", payload)
        fmt.Fprintln(os.Stderr, errMsg)
        body, _ := json.Marshal(errMsg)
        return &events.EventResponse{
            StatusCode: http.StatusBadRequest,
            Body:       body,
        }, nil
    }
}

initializer 函数

Initializer 是函数的初始化逻辑入口。单个函数内的实例级别全局初始化,推荐使用 initializer 函数进行。

函数签名

veFaaS 目前支持的 initializer 函数签名如下,您可以通过返回 error(推荐)或者 panic 来标识初始化失败。

func(context.Context) error

参数说明

context.Contexterror说明与处理常规 HTTP 请求的 handler 函数相同。

使用环境变量

对于 veFaaS 函数,您可以在控制台配置函数运行时所需的环境变量,并在代码中读取对应的环境变量,用于函数处理逻辑。对于所配置的环境变量,veFaaS 会将其注入到函数运行所在的容器中,程序可以通过语言的内置库进行读取。
例如:若您函数配置中环境变量的键(key)为envKey,运行环境读取该环境变量的代码示例如下。

import "os"

envValue := os.Getenv("envKey")