您可以使用Go請求處理常式響應接收到的事件並執行相應的商務邏輯。本文介紹Go請求處理常式的相關概念、結構特點和使用樣本。
如您需要通過HTTP觸發器或自訂網域名訪問函數,請先擷取請求結構體再自訂HTTP響應。更多資訊,請參見HTTP觸發器調用函數。
什麼是請求處理常式
FC函數的請求處理常式,是函數代碼中處理請求的方法。當您的FC函數被調用時,Function Compute會運行您提供的Handler方法處理請求。您可以通過Function Compute控制台的函數入口配置Handler。
對Go語言的FC函數而言,您的請求處理常式被編譯為一個可執行檔二進位檔案。您只需要將FC函數的請求處理常式配置項設定為該可執行檔的檔案名稱即可。
關於FC函數的具體定義和相關操作,請參見建立事件函數。
請求處理常式的具體配置均需符合Function Compute平台的配置規範。配置規範因請求處理常式類型而異。
使用樣本
在Go語言的代碼中,您需要引入官方的SDK庫aliyun/serverless/fc-runtime-go-sdk/fc,並實現handler函數和main函數。樣本如下。
package main
import (
"fmt"
"context"
"github.com/aliyun/fc-runtime-go-sdk/fc"
)
type StructEvent struct {
Key string `json:"key"`
}
func HandleRequest(ctx context.Context, event StructEvent) (string, error) {
return fmt.Sprintf("hello, %s!", event.Key), nil
}
func main() {
fc.Start(HandleRequest)
}傳入的event參數是一個包含key屬性的JSON字串,樣本如下。
{
"key": "value"
}具體的樣本解析如下:
package main:在Go語言中,Go應用程式都包含一個名為main的包。import:需要引用Function Compute依賴的包,主要包括以下包:github.com/aliyun/fc-runtime-go-sdk/fc:Function ComputeGo語言的核心庫。context:Function ComputeGo語言的Context對象。
func HandleRequest(ctx context.Context, event StructEvent) (string, error):處理請求的方法(即Handler),需包含將要執行的代碼,參數含義如下:func main():運行FC函數代碼的進入點,Go程式必須包含main函數。通過添加代碼fc.Start(HandleRequest),您的程式即可運行在阿里雲Function Compute平台。
Event Handler簽名
下面列舉出了有效Event Handler簽名,其中InputType和OutputType與encoding/json標準庫相容。
Function Compute會使用json.Unmarshal方法對傳入的InputType進行還原序列化,以及使用json.Marshal方法對返回的OutputType進行序列化。關於如何還原序列化函數的返回資料,請參考JSON Unmarshal。
func ()func () errorfunc (InputType) errorfunc () (OutputType, error)func (InputType) (OutputType, error)func (context.Context) errorfunc (context.Context, InputType) errorfunc (context.Context) (OutputType, error)func (context.Context, InputType) (OutputType, error)
Handler的使用需遵循以下規則:
Handler必須是一個函數。
Handler支援0~2個輸入參數。如果有2個參數,則第一個參數必須是
context.Context。Handler支援0~2個傳回值。如果有1個傳回值,則必須是
error類型;如果有2個傳回值,則第2個傳回值必須是error。
函數的Handler範例程式碼:
event-struct.go:
event為Struct類型的範例程式碼。event-string.go:
event為String類型的範例程式碼。event-map.go:
event為map[string]interface{}類型的範例程式碼。
更多Handler樣本,請參見examples。
Context
Context的詳細使用方法,請參見上下文。
使用HTTP觸發器調用函數
範例程式碼
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"github.com/aliyun/fc-runtime-go-sdk/events"
"github.com/aliyun/fc-runtime-go-sdk/fc"
)
type HTTPTriggerEvent events.HTTPTriggerEvent
type HTTPTriggerResponse events.HTTPTriggerResponse
func (h HTTPTriggerEvent) String() string {
jsonBytes, err := json.MarshalIndent(h, "", " ")
if err != nil {
return ""
}
return string(jsonBytes)
}
func NewHTTPTriggerResponse(statusCode int) *HTTPTriggerResponse {
return &HTTPTriggerResponse{StatusCode: statusCode}
}
func (h *HTTPTriggerResponse) String() string {
jsonBytes, err := json.MarshalIndent(h, "", " ")
if err != nil {
return ""
}
return string(jsonBytes)
}
func (h *HTTPTriggerResponse) WithStatusCode(statusCode int) *HTTPTriggerResponse {
h.StatusCode = statusCode
return h
}
func (h *HTTPTriggerResponse) WithHeaders(headers map[string]string) *HTTPTriggerResponse {
h.Headers = headers
return h
}
func (h *HTTPTriggerResponse) WithIsBase64Encoded(isBase64Encoded bool) *HTTPTriggerResponse {
h.IsBase64Encoded = isBase64Encoded
return h
}
func (h *HTTPTriggerResponse) WithBody(body string) *HTTPTriggerResponse {
h.Body = body
return h
}
func HandleRequest(event HTTPTriggerEvent) (*HTTPTriggerResponse, error) {
fmt.Printf("event: %v\n", event)
if event.Body == nil {
return NewHTTPTriggerResponse(http.StatusBadRequest).
WithBody(fmt.Sprintf("the request did not come from an HTTP Trigger, event: %v", event)), nil
}
reqBody := *event.Body
if event.IsBase64Encoded != nil && *event.IsBase64Encoded {
decodedByte, err := base64.StdEncoding.DecodeString(*event.Body)
if err != nil {
return NewHTTPTriggerResponse(http.StatusBadRequest).
WithBody(fmt.Sprintf("HTTP Trigger body is not base64 encoded, err: %v", err)), nil
}
reqBody = string(decodedByte)
}
return NewHTTPTriggerResponse(http.StatusOK).WithBody(reqBody), nil
}
func main() {
fc.Start(HandleRequest)
}
上述樣本從SDK中引入了HTTP觸發器的請求結構HTTPTriggerEvent,以及響應結構HTTPTriggerResponse。關於HTTP觸發調用的請求負載格式和響應負載格式,請參見HTTP觸發器調用函數。
前提條件
已使用上述樣本建立運行環境為Go的函數,並建立HTTP觸發器。具體操作,請參見建立事件函數和配置HTTP觸發器。
操作步驟
登入Function Compute控制台,在左側導覽列,選擇。
在頂部功能表列,選擇地區,然後在函數列表頁面,單擊目標函數。
在函數詳情頁面,單擊觸發器頁簽,在觸發器頁面擷取HTTP觸發器的公網訪問地址。
執行以下命令調用函數。
curl -i "https://http-trigger-demo.cn-shanghai.fcapp.run" -d "Hello FC!"
錯誤處理
本範例程式碼支援使用HTTP Trigger觸發器或者自訂網域名調用,如果使用API調用,但配置的測試參數不符合HTTP Trigger請求格式規範,會出現報錯。
例如,在控制台上調用,配置請求參數為"Hello, FC!",點擊測試函數按鈕,會出現報錯如下所示。
{
"statusCode": 400,
"body": "the request did not come from an HTTP Trigger, event: {\n \"version\": null,\n \"rawPath\": null,\n \"headers\": null,\n \"queryParameters\": null,\n \"body\": null,\n \"isBase64Encoded\": null,\n \"requestContext\": null\n}"
}如果想擷取原始的請求事件裝載,可以使用下面樣本中的Handler。
// GetRawRequestEvent: obtain the raw request event
func GetRawRequestEvent(event []byte) (*HTTPTriggerResponse, error) {
fmt.Printf("raw event: %s\n", string(event))
return NewHTTPTriggerResponse(http.StatusOK).WithBody(string(event)), nil
}
func main() {
fc.Start(GetRawRequestEvent)
}